关于static final String的问题

zhutao1113 2010-10-16 01:30:02

public class Test_1 {
public static final String A;
public static final String B;

static{
A = "ab";
B = "cd";
}

public static void main(String[] args) {
String s = A+B;
String t = "abcd";
if(s == t){
System.out.println("true");
}else{
System.out.println("false");
}
}
}

为什么打印结果是false。
而如果不适用静态块来初始化值,直接在定义A、B时初始化值时,会打印true。
static在类加载时就会被调用,但是为什么两者结果不同。。。
...全文
248 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovejjhao 2010-10-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zhengwei223 的回复:]

字符串对象可以存放在两个地方,字符串池(pool)和堆
编译期确定如何给一个引用变量赋值
1)String s="abc";这种形式决定将从pool中寻找内容相同的字符串并返回地址给s,pool中没有就会在pool中新建并返回地址给s
2)String s = new String("abc");这种形式决定运行期将在堆上新建字符串对象并返回给s,但这个对象不会加入到pool中
3)St……
[/Quote]

膜拜啊
小9 2010-10-16
  • 打赏
  • 举报
回复
字符串对象可以存放在两个地方,字符串池(pool)和堆
编译期确定如何给一个引用变量赋值
1)String s="abc";这种形式决定将从pool中寻找内容相同的字符串并返回地址给s,pool中没有就会在pool中新建并返回地址给s
2)String s = new String("abc");这种形式决定运行期将在堆上新建字符串对象并返回给s,但这个对象不会加入到pool中
3)String s=s1+s2;s1和s2都是变量,这种形式决定将在堆上创建s1和s2(即便s1和s2指向的对象在池中已经存在,也会将值拷贝到对象创建新对象),然后创建s1+s2并赋给s
4)String s = "ab"+"cd";同1),都是来自于池
5)String s = "ab"+s1;类似3)
6)String s = S1+S2;S1和S2是常量,常量只能赋值一次,S1,S2如果在声明的地方就赋值,那么这个值在编译期就是确定的,后面无法更改,S1+S2在执行前可确定S1/S2已经在池中存在,当然在池中进行,所以s指向pool;但是若S1,S2如果是实例常量在构造器中赋值,或是类常量在静态块中赋值,S1+S2无法确定二者皆来自于池,于是在堆上进行
所以会有以下的结果
public class Test
{
public static final String A="ab";
public static final String B="cd";

public static final String C;
public static final String D;
static{
C = "ab";
D = "cd";
}
public static void main(String[] args) {
String t = "abcd";//指向池

String s1 = "ab";//指向池
String s2 = "cd";//指向池

String s = s1+s2;//指向堆
System.out.println(s==t);//false

String ss = "ab"+s2;//指向堆
System.out.println(ss==t);//false

String sss = "ab"+"cd";//指向池
System.out.println(sss==t);//true

String ssss = A+B;//指向池
System.out.println(ssss==t);//true

System.out.println((C+D)==t);//false
}

}
小9 2010-10-16
  • 打赏
  • 举报
回复
我来

等等啊
zhutao1113 2010-10-16
  • 打赏
  • 举报
回复
回复7楼:
你的答案不在要点上,你仔细看下题目后面的说明。。
my5sky 2010-10-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 bugxing 的回复:]
帮顶,顺便问个问题
如果想单步跟踪String类源码中的compareTo方法,用eclipse应该如何操作呢
[/Quote]
按住Ctrl健,点击方法名称
my5sky 2010-10-16
  • 打赏
  • 举报
回复
首先,A与B就是两个不同的引用,s=A+B是s引用了A所引用的串池中的内容加上B所引用的串池中的内容,只是用了A与B的引用的字符串,t = "abcd"在串池中又创建了一个字符"abcd"被t引用,
在串池中总共有三个字符串,"ab","cd","abcd"分别被A,B,t引用所以打印结果是false
如果s="ab"+"cd"打印结果就为true
bugxing 2010-10-16
  • 打赏
  • 举报
回复
帮顶,顺便问个问题
如果想单步跟踪String类源码中的compareTo方法,用eclipse应该如何操作呢
zhutao1113 2010-10-16
  • 打赏
  • 举报
回复
4楼。。。你首先要明白一个东西:字符串池。。。
sdkj_cuncun 2010-10-16
  • 打赏
  • 举报
回复
二者放在内存的不同位置,==显然是false的吧
------ 2010-10-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 yudun1989 的回复:]
留名等答案 好像跟内存分配有关系
[/Quote]等待中……
voice1122 2010-10-16
  • 打赏
  • 举报
回复
留名。等待高人回答
yudun1989 2010-10-16
  • 打赏
  • 举报
回复
留名等答案 好像跟内存分配有关系

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧