日期:2014-05-20  浏览次数:20805 次

java基础 !!
解释下为什么 结果是这样的?不应该是三个true吗?
public class A1 {

/**
 * @param args
 */
final String s1;
final String s2;
final String s3="java";
{
s1 = "java";
}
public A1(){
s2 = "java";
}
public void display(){
System.out.println(s1+s1=="javajava");
System.out.println(s2+s2=="javajava");
System.out.println(s3+s3=="javajava");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
A1 a = new A1();
a.display();
}

}
结果
false
false
true
------解决方案--------------------
个人理解,如有不对的地方,欢迎指正。
1、Java的对象分为两种,数据对象和引用对象。String属于引用对象, == 比较的是两个对象的引用地址也就是内存地址
2、String常量池:Java为了更有效地使用内存,JVM留出一块特殊的内存区域,被称为“String常量池”,当编译器遇见String常量的时候,它检查该池内是否已经存在相同的String常量;
3、第一次使用 "javajava" 这个对象时,JVM会隐式的声明一个String对象,这个String对象被放在了常量池中。s3的值在编译时就已经确认了,而s1和s2则是在运行时才能确认;
public class A1 {

/**
 * @param args
 */
final String s1;
final String s2;
final String s3="java";
{
s1 = "java";
}
public A1(){
s2 = "java";
}
public void display(){
System.out.println(s1+s1);
System.out.println(s2+s2);
System.out.println(s3+s3);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
A1 a = new A1();
a.display();
}
}


public void display()
  {
    System.out.println(this.s1 + this.s1);
    System.out.println(this.s2 + this.s2);
    System.out.println("javajava");
  }


反编译上面的代码,发现s3+s3其实在编译时已经确认了,所以说,这个和直接写成 “javajava”效果是一样的
而s1 + s1 这个是在运行时才确认的,运行时的对象都是存储于堆中的,那么自然,对于这个对象 s1 + s1 它在内存中的地址也存在于堆中,只是它指向了常量池的一个 "javajava" 对象。也就是说  s1 + s1 表示的是一个堆中的地址,但是它的值是常量池中 "javajava" 对象的地址值