string a=“aa”;
string不是一个基本的数据类型,而是引用类型,对于以上简单的一句话再java编译器看来再编译阶段是可以确定下来的,那么就把“aa”对象存放在当前class文件的常量池区域(注意不是堆,具体来说是perm区),常量池同样也是可以再运行时扩充的,例如“xxx”.intern()的调用,就是运行时向class的常量池中注入数据,不断注入可以导致java.lang.outofmemory:permgen space异常。流程大概是先拿这个字符串与常量池中得每个字符串进行equels比较,如果存在一致的则返回常量池的引用,如果都不存在再注入常量值并返回当前地址,可见string.intern()的效率并不高。
private static void test1(){
string a = “a” + “b” +1;
stirng b = “ab1”;
system.out.println(a==b);
}
显然返回结果为true
关于”==“:对于基础数据类型来说==是比较基本数据类型的值如(byte,short,int,float,char,double,long,boolean),而对于引用类型,比较的是两个引用对象的逻辑地址
关于equels和hashcode():object类的equels方法默认就是比较的两个对象引用的逻辑地址(return (this == obj);),equels的设计就是要子类来自己实现比较两个相同的子类(对于不同的子类来比较是没有任何意义的,所以看到很多equels的实现中都是先判断两个对象是不是属于一个类)对象是否是相等的,这里不是引用的地址是否相等。java默认的hashcode方法提供了对象的hash值,他是一个native方法(native的方法调用成本还是很高的),他的返回值与system.identifyhashcode(object)方法的返回值一致,通常情况下是对象头部的一部分二进制组成的数字,hashcode方法可以说是标识对象,用以再hash算法中将对象散列开。string类重写了hashcode方法,需要遍历char[]的所有的char来生成对应的string类的hashcode,对象其实equels方法和hashcode本身并没有什么关系,只是一些类的使用上导致了大家认为重写equels()方法就一定要重写hashcode()方法。如hashmap(还有hashset,但是hashset是使用hashmap来实现的),hashmap中put一个元素的过程是先调用key的hashcode方法,根据这个方法的返回值和hashmap中entity数组的长度计算出entity的index,如果这个index上已经有了元素的话在调用key的equels方法进行比较,如果存在想通的就替换,如果不存在就插入链表。
关于编译时优化:对于编译器来说编译时优化秉承的原则就是能确定的就优化(例如final),确定不了的就不处理,对于final类型的变量进行优化,对于方法调用不进行优化,注意string a=“a” + “b”是在编译时优化为a=“ab,而string a=“a” string b=a+”b”在编译时优化为stringbuffer的拼接
以上就是解读java中的string类的详细内容。