首页 > 试题广场 >

观察下列代码,分析结果() String s1 = "cod

[单选题]

观察下列代码,分析结果()

String s1 = "coder";     
String s2 = "coder";     
String s3 = "coder" + s2;     
String s4 = "coder" + "coder";     
String s5 = s1 + s2;            
System.out.println(s3 == s4); 
System.out.println(s3 == s5);    
System.out.println(s4 == "codercoder");
  • false;false; true;

  • false;true; true;

  • false;false; false;

  • true;false; true;

引用类型判断时,==判断的是地址是否相等。如果用常量字符串来定义的(如s1,s2,s4)会存在常量池里面;用变量定义的就不会(如s3,s5)。所以上面的状态就是s1==s2;s4==“codercoder”;s3!=s4;s3!=s5。
发表于 2022-01-17 16:48:44 回复(13)
这道题官方的解析有错, s5并不是指向常量池, 而是指向堆
定义字符串的时候看定义时等号右边拼接字符串时有没有使用到变量, 如果有, 则重新创建一个新的对象

发表于 2022-10-23 10:45:26 回复(5)

Java内存结构包含以下部分:

1、栈区:由编译器自动分配释放,具体方法执行结束后,系统自动释放JVM内存资源。

其作用有保存局部变量的值,包括:1.用来保存基本数据类型的值;2.保存类的实例,即堆区对象的引用。也可以用来保存加载方法时的帧。

2、堆区:一般由程序员分配释放,JVM不定时查看这个对象,如果没有引用指向这个对象就回收。

其作用为用来存放动态产生的数据,包括new出来的实例,字符数组等。

同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法。

3、数据区:用来存放static定义的静态成员。

4、常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于堆中
public static void main(String args[]) {
       // 字符串常量,分配在常量池中,编译器会对其进行优化,  Interned table
       // 即当一个字符串已经存在时,不再重复创建一个相同的对象,而是直接将s2也指向"hello".
       String s1 = "hello";   
       String s2 = "hello";
       // new出来的对象,分配在heap中.s3与s4虽然它们指向的字符串内容是相同的,但是是两个不同的对象.
       // 因此==进行比较时,其所存的引用是不同的,故不会相等
       String s3 = new String("world");      
       String s4 = new String("world");
       System.out.println(s1 == s2);   // true
       System.out.println(s3 == s4);   // false
       System.out.println(s3.equals(s4));   // true   
       // String中equals方法已经被重写过,比较的是内容是否相等.
   }
编辑于 2022-02-16 21:29:10 回复(7)
s=“a”+“b” 是字符串拼接, s = "a"+b 则是重新创建一个对象
发表于 2022-10-14 16:42:31 回复(0)
发表于 2022-08-20 09:20:25 回复(2)
一共有四种情况的字符串对象放在常量池: 1.直接“.…”得到的字符串 2.通过“…”+“…”直接相加的字符串 3.两个指向“...”的final常量拼接的结果 4.所有字符串对象.intern()得到的结果
发表于 2022-08-19 09:38:28 回复(2)
我想说的是S5应该不是放入常量池的吧,运行结果如下;


发表于 2022-05-09 22:51:24 回复(5)
String s1 = "coder";     
String s2 = "coder";     
String s3 = "coder" + s2;     
String s4 = "coder" + "coder";     
String s5 = s1 + s2;            
System.out.println(s3 == s4); 
System.out.println(s3 == s5);    
System.out.println(s4 == "codercoder");
这是一段JAVA代码,在JAVA语言中内存分配是除了堆(heap——程序员手动分配)、栈(自动分配)外,还有一个区域叫常量区,其中常量区的例子如下:
// 字符串常量,分配在常量池中,编译器会对其进行优化,  Interned table
// 即当一个字符串已经存在时,不再重复创建一个相同的对象,而是直接将s2也指向"hello".
String s1 = "hello";   
String s2 = "hello";
但是若是变量定义赋值,或者new,就会在内存中新找一段地址。
而题目中的 == 判断的是地址是否相同
所以结果如答案所示
System.out.println(s3 == s4);   //false
System.out.println(s3 == s5);   //false
System.out.println(s4 == "codercoder");  //true
本题需要判断变量的地址是否相同,同时JAVA内存分配示意图如下:

发表于 2022-03-01 12:13:32 回复(1)
在Java中,字符串的比较有两种方式,一种是使用`equals()`方法,这种方式是比较字符串的内容是否相同,另一种是使用`==`操作符,这种方式是比较两个字符串对象是否是同一个对象(即比较他们在内存中的地址)。

对于这段代码,首先需要理解Java中的字符串常量池(String Constant Pool)。字符串常量池是Java为了优化字符串的创建而设立的。当我们创建一个字符串常量,如`String s = "coder";`,Java会首先在字符串常量池中查找是否有相同的字符串,如果有,就返回该字符串的引用,如果没有,就在池中创建一个新的字符串。

然后我们来分析这段代码:
String s1 = "coder";     // 在字符串常量池中创建一个字符串"coder",s1指向它
String s2 = "coder";     // 在字符串常量池中找到已经存在的"coder",s2指向它,所以s1和s2指向同一个对象
String s3 = "coder" + s2;     // 这里涉及到字符串的连接,会创建新的字符串对象,s3指向这个新的对象
String s4 = "coder" + "coder";     // 这里是常量字符串的连接,编译器会在编译期间就完成连接,所以s4指向字符串常量池中的"codercoder"
String s5 = s1 + s2;            // 这里也是字符串的连接,会创建新的字符串对象,s5指向这个新的对象
System.out.println(s3 == s4); // s3和s4指向的不是同一个对象,所以结果为false
System.out.println(s3 == s5);    // s3和s5指向的不是同一个对象,所以结果为false
System.out.println(s4 == "codercoder"); // s4和"codercoder"都指向字符串常量池中的同一个对象,所以结果为true
所以,这段代码的输出应该是:
false
false
true
发表于 2023-11-07 12:07:05 回复(0)
这道题官方的解析有错, s5并不是指向常量池, 而是指向堆 定义字符串的时候看定义时等号右边拼接字符串时有没有使用到变量, 如果有, 则重新创建一个新的对象
发表于 2022-10-25 00:41:59 回复(0)
/**对class文件反编译
  *在JVM中对String的优化
  *采用字面量赋值时 如果+号两边不是变量,JVM会自动进行字符的拼接。
  *如果+号两边有变量,JVM不会对这一行进行任何操作
  **/
String a="codercoder";
String b="coder";
String c="coder"+"coder";//==>String c="codercoder";
String d="coder"+b;//==>String d=new String("coder"+b);
//a==c  a!=d

发表于 2022-12-09 17:45:58 回复(0)
深入理解可以看看String的itern方法
发表于 2022-07-21 18:40:48 回复(0)
对于"coder" + s2使用到了StringBuilder的拼接操作,会在堆中创建一个StringBuilder对象;对于"coder" + "coder"是在常量池开辟一个空间存放了"codercoder"字符串,如果已经存在了"codercoder",则直接使用这个字符串




发表于 2024-04-25 18:37:40 回复(0)
s3和s5貌似都是创建了新的对象,尽管内容一样,但是内存地址不一样,所以二者不相等!
编辑于 2024-04-09 23:05:29 回复(0)

在两个String变量相加的时候,变量不是显式已知的(编译器不知),底层实际调用了StringBuffer的append方法,s3指向堆区而不是常量池。

在两个String字面量相加的时候,由于字面量是显式已知的,编译器将其优化为相加的结果并存入常量池。

发表于 2024-03-31 21:50:16 回复(0)
s3是通过拼接变量s2和常量字符串"coder"得到的,这种情况下,s3会在堆内存中创建一个新的字符串对象,因为其中包含了变量。 s4是通过拼接两个常量字符串"coder"得到的,编译器会将这个拼接优化为一个常量字符串"codercoder",并放入字符串常量池中。 s5是通过拼接两个变量s1和s2得到的,这种情况下,会在堆内存中创建一个新的字符串对象。 因此,对于s3和s4,它们实际上指向了相同的常量字符串对象,所以s3 == s4会返回true。而对于s3和s5以及s4和常量字符串"codercoder"的比较,由于它们指向的对象不同,所以s3 == s5和s4 == "codercoder"会返回false。
编辑于 2024-03-28 10:12:54 回复(0)
s3是重新创建一个对象
发表于 2024-02-17 00:19:40 回复(0)
官方解析有错误,s5指向堆中的对象,而不是字符串常量池中的对象。
发表于 2023-12-11 11:30:29 回复(0)
问一下大家,这样想对吗
发表于 2023-10-09 16:05:50 回复(0)

1常量+常量:结果是常量池地址。且常量池中不会存在相同内容的常量。

2常量与变量变量与变量:结果在堆中,返回堆空间中地址

3拼接后调用intern方法:返回值常量池中地址,和(1)结果一样。

发表于 2023-10-09 10:05:27 回复(0)