Java String类对象引用、字符串常量和String Pool 相互关系的学习
2014-06-22 16:21
489 查看
Java中的数据类型及其存放的内存位置
栈:存放基本数据类型及对象的引用堆:new 操作符建立的对象(包括数组)
静态域:static定义的静态成员变量
常量池:存放常量
代码及输出结果及原理解释
public class StringTest { /** * @param args the command line arguments */ public static void main(String[] args) { String a = "hello"; // 1.栈内存中创建一个String类型的引用变量a; // 2.在字符串常量池中寻找有没有"hello",如果没有则在字符串常量池中创建对象并将对象的地址赋给a // 如果有则将地址直接赋给变量a。这里因为字符串常量池中没有"hello",因此需要创建一个新的对象。 // 3.该表达式创建了1个引用1个对象。 String b = "hello"; // 1.栈内存中创建一个String类型的引用变量b; // 2.在字符串常量池中寻找有没有"hello",如果没有则在字符串常量池中创建对象并将对象的地址赋给b // 如果有则将地址直接赋给变量a。这里因为字符串常量池中有"hello",因此不需要创建一个新的对象。 // 3.该表达式创建了一个引用。 String newA = new String("hello"); // 1.栈内存中创建一个String类型的引用变量newA; // 2.在字符串常量池中寻找有没有"hello",如果没有则在字符串常量池中创建对象 // 如果有则将地址直接返回对象引用。 // 3.通过向构造函数传递另外一个字符串对象的引用在堆中创建一个新的对象,并将地址 // 赋给引用变量newA。 String c = "hel"; String d = "lo"; final String finalc = "hel"; // 编译期间能够确定的引用常量,那么编译期间用字符串常量替换该引用。 final String finalgetc = getc(); // 编译期间不能够确定的引用常量。 System.out.println("a == b ? " + (a == b)); // true // a 和 b 都指向的是String Pool中的"hello"对象。 System.out.println("a == newA ? " + (a == newA)); // false // newA指向的堆中的"hello"对象 System.out.println("a == hel + lo ? " + (a == "hel" + "lo")); // true // 编译器会将"hel" + "lo"优化,合成"hello"。 System.out.println("c == finalc ? " + (a == finalc + "lo")); // true // 编译器会用"hel"替换finalc,因此结果和上一个表达式是一样的。 System.out.println("c == finalc ? " + (a == finalgetc + "lo")); // false // 由于finalgetc是一个编译期间不能确定的引用,只有在运行期间才能确定。 // 因此它所引用的内容和"lo"相连接,在堆中创建一个新的String 对象。所以两者的 // 地址是不一样的。 System.out.println("a == c + d ? " + (a == c + d)); // false // 道理同上。 System.out.println("finalgetc == finalc ? " + (finalgetc == finalc)); // true // 两者所指向的都是String Pool中"hel"的地址。 // String::intern()函数的含义:当调用 intern 方法时,如果池已经包含一个 // 等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回 // 池中的字符串。否则,将此String 对象添加到池中,并且返回此String 对象的引用 System.out.println("a.intern() == b.intern()"+ (a.intern() == b.intern())); // true // a调用intern()和b调用intern() 方法返回的都是String Pool 中的"hello"的地址 System.out.println("a.intern() == b.intern()"+ (a.intern() == newA.intern())); // true // 当a调用intern()和newA调用intern() 方法返回的都是String Pool 中的"hello"的地址 System.out.println("a.intern() == b.intern()"+ (newA == newA.intern())); // false // newA调用intern() 方法返回的都是String Pool 中的"hello"的地址,newA指向的是堆中的对象。 } private static String getc() { return "hel"; } }
程序运行结果
相关文章推荐
- java学习心得:关于对象与引用变量的关系的理解
- java学习笔记:java的多态,子类和父类的相互转换,父类引用指向子类的对象
- python学习(九)python中的变量、引用和对象的关系
- Java学习笔记---6.面向对象编程01-类对象的构建及对象的引用传递
- 由Equals()引发的对对象的引用与对象(即实例)的关系的思考
- C++学习笔记(13)——利用对象、引用、指针调用虚函数
- UML描述对象和类之间的相互关系
- 持有对象的引用 -Java学习笔记(33)
- 微软企业库4.1学习笔记(二)各功能之间的依赖关系以及对象创建
- UML类图简单学习 各种对象、关系UML表示法
- UML类图简单学习 各种对象、关系UML表示法
- 微软企业库4.1学习笔记(二)各功能之间的依赖关系以及对象创建
- 学习笔记之什么是持久化和对象关系映射ORM技术
- 微软企业库4.1学习笔记(二)各功能之间的依赖关系以及对象创建
- 微软企业库5.0学习笔记(六)创建并引用企业库对象
- 如何处理包内单元的相互引用关系
- java学习笔记:引用与对象(1)
- Microsoft .NET Pet Shop 4.0 学习之旅(三) - 项目的引用关系2
- 学习笔记之什么是持久化和对象关系映射ORM技术
- 类与对象02_对象和类与对象关系_旺旺老师Java学习解决方案_第一季