如下代码
String s1="abc";
String s2="abc"+"d";
String s3=s1+"d";
String s4="abcd";s2==s4; trues3==s4; false我们知道s2,s4都是指向常量池中内存"abcd",所以地址相同那么s3指向哪里,各位知道吗????
String s1="abc";
String s2="abc"+"d";
String s3=s1+"d";
String s4="abcd";s2==s4; trues3==s4; false我们知道s2,s4都是指向常量池中内存"abcd",所以地址相同那么s3指向哪里,各位知道吗????
解决方案 »
- 请问各位高手,用1,2,2,3,4,5这六个书字,用Java写一个main函数,打印出所有的排列,如:512234,412345.要求4不能在第三位,3与5不能
- java swing中放html的思路和肯定
- 高分求救 我在UNIX系统上 读取文件中文乱码问题
- 一个出错报告
- 弱问:try块中的结果如何返回?
- BigInteger类isProbablePrime函数的参数是什么意思啊?
- 高分求高效方法实现(2)
- 有一些问题想请教一下各位大虾,请各位回答时尽量具体点哦!有很多分哦!
- 谁有好用的JB5.0的注册号呀。
- 请问有谁有jbuilder3.5的密码啊
- 急!!关于JSR82 LocalDevice 获取本地名称
- Jdialog弹出的frame无法获得焦点,怎么办?
就此我写了下面的代码,结果是s2,s3,s4这三个引用都指向了同一对象,我也不知道是什么回事,和楼上一样,期待高手解答。个人认为,JVM虚拟机应该做了优化吧,s2,s3,s4表达式右边的结果都是“abcd”,JVM说既然都是指向同一个值,何必要生成三个对象呢?生成一个不就得了吗?不知道这种理解对不?
public class test
{
public static void main (String[] args) {
String s1="abc";
String s2="abc"+"d";
String s3=s1+"d";
String s4="abcd";
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println(s4.hashCode());
}
}输出结果:
96354
2987074
2987074
2987074
例子:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
这个是纯粹是因为编译器优化而已。String s2="abc"+"d"; 编译器会直接变成 String s2="abcd"; 因为编译器知道它可以计算出来
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count; for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
这个完全是根据字符串的内容生成的hash值,所以你要是重写了String的hashCode方法,例如用String对象的引用作为hash值,那么你再打印一下,结果就会不同了。
s2="abcd";
s4="sbcd";
都是指向常量池,所以相等。
但是String s3=s1+"d";
在编译器处理后变成了
s3=new StringBuilder().append(s1).append("d").toString();
在toString函数当中会创建一个新的String对象,这个对象是堆中的,所以和s4
不相等。
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}这个是StringBuilder中的toString方法,是创建了一个新的String对象。
你可以用JAD等反编译工具看看,String s2="abcd"; 这个是反编译出来的结果。所以s2 == s4 ,但是s3 != s4编译器会尽可能将可以计算出来的结果都预先计算的。