关于String对象的比较

简介: 1、String对象的比较   String 是一个常量,从String类中的代码可以看出。String类内部是通过char数组来存储字符串,这个char数组是被声明成final的。 1 // Java中只要使用了new 则生成一个新的对象,该对象永远在堆中,stringpool初始化为空...

1、String对象的比较

  String 是一个常量,从String类中的代码可以看出。String类内部是通过char数组来存储字符串,这个char数组是被声明成final的。

 1 // Java中只要使用了new 则生成一个新的对象,该对象永远在堆中,stringpool初始化为空,是由string类单独维护的
 2 // 首先在stringpool中找abc对象,若没有则在stringpool创建abc对象,之后在堆中生成一个abc对象,即生成两个对象
 3 String s = new String("abc");// s指向的是堆中的对象
 4 // 首先从stringpool中去查找是否有abc对象,若有,则不生成(若没有则在stringpool生成abc对象,在用s1指向abc对象)。再用s1指向stringpool中的abc对象
 5 String s1 = "abc";
 6 // 首先在stringpool中找abc对象,若有,则不创建。之后在堆中生成一个abc对象,并把s2指向堆中的对象
 7 String s2 = new String("abc");
 8 
 9 System.out.println(s == s1);
10 System.out.println(s == s2);
11 System.out.println(s1 == s2);

代码执行内存中的变化如下:

代码执行完第3行的时候,此时会在stringpool中生成了一个abc对象,接着在堆中生成一个abc对象,并把堆中生成的abc对象的引用返回给s。

代码执行完第5行的时候,因为此时stringpool中已经有了一个abc对象,所以不会继续在stringpool中创建abc对象,s1就直接指向了stringpool中这个abc对象。

代码执行完第5行的时候,因为此时stringpool中已经有了一个abc对象,所以不会继续在stringpool中创建abc对象。而是在堆中生成一个abc对象,并把s2指向它。

 对于引用类型来说,== 判断的是地址,对于原始数据类型来说==比较的是字面值,所以执行输出的结果如下:

false
false
false

内存示意图如下:

2、String对象的intern()方法

  intern()的含义(返回的都是stringpool中的对象)若stringpool中包含abc,则返回stringpool中的abc对象的地址。若stringpool中不存在abc对象,则在stringpool中创建abc对象,并且把stringpool中abc对象的地址返回。

1 String s = new String("abc");
2 String s1 = "abc";
3 String s2 = new String("abc");
4 
5 System.out.println(s == s.intern());
6 System.out.println(s1 == s1.intern());
7 System.out.println(s.intern() == s2.intern());

第5行代码执行的时候,此时stringpool已经有了一个abc对象,s.intern()会将stringpool中的abc对象返回,而s指向的是堆中的abc对象,故为假。

第6行代码执行的时候,此时stringpool已经有了一个abc对象,1s.intern()会将stringpool中的abc对象返回,而s1指向的也是在stringpool中的abc对象,故为真。

第7行代码执行的时候,此时stringpool已经有了一个abc对象,s1.intern()和s2.intern()都是将stringpool中的abc对象返回,故为真。

执行的结果如下

false
true
true

3、关于String中“+”操作

  a、当 + 两边都是字面值(常量值)的时候,执行完+后,会首先判断stringpool值是否存在hello对象,若有则返回stringpool中的hello对象的地址。(若没有则创建,并返回stringpool中的对象)

  b、当 + 操作时,若+两边有一个不是字面值的常量的时候,(不会检查stringpool,)java会直接在堆中生成一个hello对象,并把堆中的hello对象返回

1 String hello = "hello";
2 String hel = "hel";
3 String lo = "lo";
4          
5 System.out.println(hello == "hel" + "lo");//编译后的代码为System.out.println(hello == "hello");
6 System.out.println(hello == "hel" + lo);//编译后的代码为System.out.println(hello == (new StringBuilder("hel")).append(lo).toString());

第5行代码执行的时候,此时stringpool已经有了一个hello对象,"hel" + "lo"也是将stringpool中的hello对象返回,故为真。

第6行代码执行的时候,"hel" + lo因为lo不是一个常量,所以"hel" + lo ,java会在堆中生成一个hello对象并返回。所以这个两个对象一个在stringpool中,一个在堆中,故为假。

执行结果如下:

true
false

4、关于String中concat(String str)方法

  concat方法主要是将两个字符串连接起来,当传入的参数长度为0的时候,返回调用对象的本身;否则就对两个字符串进行拼接,生成一个新的对象返回。

1 String hello = "hello";
2 String hel = "hel";
3 String lo = "lo";
4 
5 System.out.println(hello == hel.concat(lo));

  执行结果如下:

false

  通过查看String类中concat(String str)方法可以得知结果,源码如下:

 1 public String concat(String str) {
 2     int otherLen = str.length();
 3     if (otherLen == 0) {
 4         return this;
 5     }
 6     int len = value.length;
 7     char buf[] = Arrays.copyOf(value, len + otherLen);
 8     str.getChars(buf, len);
 9     return new String(buf, true);
10 }

  第3行判断传入的参数长度是否为0,如果为0就将调用对象返回;如果不为0就进行拼接,最后以new的方式在堆中创建一个新的String对象,并返回。所以当参数长度不为0的时候使用concat方法返回的对象总是在堆中新创建的对象。故进行对象比较为false。

目录
相关文章
|
9月前
|
Java 开发者
课时45:String对象常量池
本次课程的主要讨论了对象池的概念及其在Java开发中的应用。首先,介绍了静态常量池和运行时常量池的区别。讨论了静态常量池和运行时常量池在实际开发中的作用,以及如何理解和应用这些概念。 1.常量池的分类 2.静态常量池和运行时常量池的区别
103 1
|
9月前
|
存储 JavaScript Java
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
168 1
|
缓存 Java
Java中循环创建String对象的内存管理分析
Java中循环创建String对象的内存管理分析
164 2
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
281 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
存储 JavaScript 前端开发
JavaScript 字符串(String) 对象
JavaScript 字符串(String) 对象
142 3
|
存储 程序员 API
八股day05_API、String对象和集合
day05_API、String对象和集合
|
对象存储
String_s1_=_new_String(“abc“);这句话创建了几个字符串对象?
String_s1_=_new_String(“abc“);这句话创建了几个字符串对象?
|
Java 程序员 编译器
new String(“hello“)之后,到底创建了几个对象?
最近,有很多优秀的程序员从大厂毕业, 再加上大环境的影响,很多正在找工作的小伙伴也感觉技术面试越来越难,基本上都会问技术底层原理,甚至有些还会问到操作系统层面的知识。 如果技术功底不扎实,确实很难找到合适的岗位。
244 0
|
存储 Java
构造String问题之在JDK 9及更高版本中,直接访问String对象的coder和value属性,如何实现
构造String问题之在JDK 9及更高版本中,直接访问String对象的coder和value属性,如何实现
172 0
|
存储 缓存 安全
Java性能优化(二):Java基础-String对象及其性能优化
在深入探讨了String字符串的性能优化后,我们认识到优化字符串处理对提升系统整体性能的重要性。Java在版本迭代中,通过精心调整成员变量和内存管理机制,不断对String对象进行优化,以更高效地使用内存资源。String对象的不可变性是Java语言设计中的一个关键特性,它不仅确保了字符串的安全性,也为字符串常量池的实现提供了基础。通过减少相同值的字符串对象的重复创建,常量池有效地节约了内存空间。然而,不可变性也带来了挑战。在处理长字符串拼接时,我们需要显式使用类来避免性能下降。
283 1