首页 > 试题广场 >

下面程序的运行结果是

[单选题]
下面程序的运行结果是
String str1 = "hello";
String str2 = "he" + new String("llo");
System.err.println(str1 == str2);
  • true
  • false
  • exception
  • 无输出
这个问题我试着回答一下,同时也是相互学习。String str1= "hello", String str2="he"+"llo";之所以str1==str2返回true是因为两者都是在字符串常量池中(由于初始化就会在此区域分布内存)而常量池中的有个与栈区类似的特性,就是当str2指向的常量在常量区已存在时,他不会创建新的内存空间来存此常量,而是指向已有常量的内存(应该是以此节约空间),此时str1与str2这两个引用变量的值都是存"hello"的内存空间地址,但是String str3= "he"+a;String a="llo";时str1==str3返回的为false,是因为:str1指向的hello在编译期一如既往的还是分配在常量区内,a指向的llo也在常量区,虽然str3也是初始化但是编译器无法判断a这货到底是什么个情况,进而不会将str3的等号右侧声明在常量区内,而是在通过构造时在堆区中的非常量池外的内存中声明,至此str3与str1不止是分配内存的时期不同(一个在编译期,一个在运行期)而且在内存空间的区域也不同,上面最高票答案只区分了时间没区分空间。
发表于 2016-08-16 10:24:23 回复(14)
false
发表于 2015-04-14 17:01:02 回复(0)
String str1 = "hello";这里的str1指的是方法区的字符串常量池中的“hello”,编译时期就知道的; String str2 = "he" + new String("llo");这里的str2必须在运行时才知道str2是什么,所以它是指向的是堆里定义的字符串“hello”,所以这两个引用是不一样的。

如果用str1.equal(str2),那么返回的是True;因为两个字符串的内容一样。

发表于 2015-08-03 22:52:15 回复(11)
str1指向常量池中的字符串;str2是通过StringBuilder类new出的对象,指向堆。故为false
发表于 2016-06-14 22:36:03 回复(5)
选B是没问题的
主要因为,编译器没那么智能,它不知道"he" + new String("llo")的内容是什么,所以才不敢贸然把"hello"这个对象的引用赋给str2.主要因为new String("llo")外边包着一层外衣呢
如果语句改为:"he"+"llo"这样就是true了
本题类似于:
a="ab"
b="abc"
c=a+"c"
d="ab"+"c"
b==c ??? true or false 
d==c ???  true or false 
b==d ???  true or false 

final String x="x";
String y = "y";
String z1 = "xy";
String z2 = x+"y";
String z3 = x+y;
z1 == z2?true:false
z1==z3?true:false 
编辑于 2015-08-13 14:58:38 回复(10)

发表于 2019-06-18 09:29:07 回复(1)
字符串拼接时,只要出现new生成的字符串对象,则新的字符串对象会占用堆空间,相当于new。因此str1和str2有不同的地址指向,故为false
发表于 2018-09-02 08:30:31 回复(3)
当创建了匿名对象new String("llo")时,会在堆内存中开辟空间,地址值不一样了
发表于 2015-08-08 10:44:38 回复(0)
system.err和system.out的区别??是啥
发表于 2016-06-22 23:42:43 回复(3)
String str1 = "hello";将“hello”分配在常量池中,String str2 = "he",“he”也在常量池中,但是+右边的“llo”是new出来的,肯定会分配到堆区中,两个拼接产生的字符串显然也在堆区中。

发表于 2020-01-30 11:25:02 回复(1)
System.err是一个PrintStream流。System.err与System.out的运行方式类似,但它更多的是用于打印错误文本。一些类似Eclipse的程序,为了让错误信息更加显眼,会将错误信息以红色文本的形式通过System.err输出到控制台上。
发表于 2019-03-20 08:08:58 回复(0)
我以为System. err.println输出不了😂
发表于 2018-06-28 01:05:35 回复(2)
因为str2中的llo是新申请的内存块,而==判断的是对象的地址而非值,所以不一样。如果是String str2 = str1,那么就是true了。
发表于 2015-11-08 18:14:33 回复(1)
B.
==是比较对象的引用是否一致(实际上就是比较hashcode),str1和str2尽管内容相同,但是是两个对象,所以false。若直接定义String str3="hello",则编译器,自动会把str3和str2认为是同一对象的不同引用,str1 == str3返回true。
编辑于 2015-08-02 11:05:36 回复(2)
str1指向的是常量池中的的字符串,str2是通过StringBuilder类new出来的对象,是指向堆的,这里==比较的是两个引用类型,故比较的是地址值,所以结果为false
发表于 2022-04-03 15:19:40 回复(0)
java编译器会对字符串进行处理,常量字符串会合并,但是运行时创建的都是新的内存地址
发表于 2016-05-24 14:26:00 回复(2)
不明白的我,还以为只能显示错误信息。
out:

“标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。对于简单独立的 Java 应用程序,编写一行输出数据的典型方式是:System.out.println(data);

err:

“标准”错误输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。按照惯例,此输出流用于显示错误消息,或者显示那些即使用户输出流(变量 out 的值)已经重定向到通常不被连续监视的某一文件或其他目标,也应该立刻引起用户注意的其他信息。 
发表于 2020-07-23 08:42:47 回复(0)

public static void main(String[] args)
{
//s1直接引用常量池中的"hello",如果常量池中还没有,就再常量池中创建
String s1="hello";
String s2="he";
String s3="llo";
//s4后面的字符串值在编译时就可以确认下来
//s4直接引用常量池中的"hello"
String s4="he"+"llo";
//s5后面的字符串值在编译时不可以确认下来
//不能引用常量池中的字符串
String s5=s2+s3;
String s6= "he" + new String("llo");
System.out.println(s1==s4);//输出true
System.out.println(s1==s5);//输出false
System.out.println(s1==new String"hello");//输出false,new string是在运行时创建出来,被保存在堆中,不放在常量池中
System.err.println(s1 == s6);//false,同s5
}

发表于 2019-02-28 20:42:38 回复(0)
其实有一个快速的方法记住这样的题型:
字面量的字符串相当于常量,
1、常量 + 常量 = 常量(这些在编译的时候保存在常量池中,是同一个对象)
2、常量 + 变量 = 变量(不属于常量池,分配在堆区,所以不是同一个对象)
发表于 2018-08-13 16:25:23 回复(5)
String a="a,b,c"指向的是字符串常量池中的hello,在编译器就可以确定,String str2="a,"+newString("b,c");这里在编译器不知道new出来的是什么类型的,只有运行时才知道str2是什么,所以存放在堆中
发表于 2016-06-28 21:36:04 回复(0)