常量池---知识网 【Java_基础】java中的常量池

前言

  知识网:

  • 常量池
  • 变量
  • 常量
  • 对象字面量      

什么是常量池

  常量池是JVM中线程共享的一块内存区域,Java会将 编译期就已经确定的数据 保存在常量池中,这样就避免了频繁的创建与销毁对象对系统性能的影响。

  常量池中主要存放的就是 final常量 的值以及 对象字面量 的值。

  常量池中是不会存在相等的数据的,因为在编译期间,每当常量需要赋值的时候,就回去常量池检测有没有该值,如果有则将该值的地址引向常量,如果没有该值,则在常量池中创建该值,再将值得内存地址引向常量。

知识撒网

  Java代码执行过程: 我们知道,Java程序代码为实现跨平台会经历两个时期:一个是编译期、另一个是运行期。

为了方便理解,我们暂时将第二个时期再次拆分为解释期、运行期。如下:

  第一个阶段我们称为编译期此时Java代码会通过javac编译成class文件。
   
  第二个我们可以称为解释期此时classloader(类加载器)会将class文件中的成员变量,构造方法,成员方法等加载到内存中去。   第三个我们将之称为运行期此时就是我们熟悉的创建对象,开辟空间、分配内存、执行代码了。  

  变量:变量其实就是代表一个“可操作的存储空间”,空间位置是确定的,但是里面放置的是什么值是不确定的。我们可以通过变量名来访问“对应的存储空间”,从而操作这个“存储空间”存储的值。 

  常量:简单理解就是一切由final关键字修饰的变量都是final常量。常量需要在初始化的时候就赋值,而且一旦赋值就不能再更改。说白了就是由final声明一个固定值。

扫描二维码关注公众号,回复: 7667788 查看本文章

  对象字面量:我们需要一个对象通常会new一个对象实例出来,而对象字面量则是直接把常量给对象赋值无需new出来的对象。例如:String对象以及部分基本类型的包装类对象。如下:

  

Integer a = 30 ;  //在常量池中。
Integer b = new Integer(40);  //在堆内存中开辟空间。
Integer c = 30;  // 在常量池中,和a指向的地址一致。

String str1 = "你";  //在常量池中。
String str2 = "好";  //在常量池中。
String str3 = new String("吗");  //在堆内存中开辟空间。
String str4 = "你" + "好";  // "你好" 在常量池中。PS:两个确定的值,拼接还是固定值。
String str5 = str1 + str2 ;//在堆内存中。PS :str1、str2 运行期间指向的值可能变,所以是不固定的  str4 != str5  俩人不是一个世界的(内存地址不一样)
String str6 = str5.intern(); // 在常量池中 intern()方法会在常量池中查找是否有值相等的字符串,有则返回引用,没有则在常量池添加该字符串。所以 str4 == str6

//PS:创建Str3的时候,实际上产生了一个或者两个对象 这和String的构造器有关 public String(String original) {...}  
//可以看出String的构造器是需要一个字符串作为参数的。此时new String(...)会在堆中创建一个对象,此时堆内存中开辟了相应的空间,
//而需要的参数字符串会去常量池中查找有没有相同的值,有就直接引用(此时就产生一个对象),没有则会在堆内存开辟空间存入该值,并将该空间地址引向str3(此时则产生两个对象)。
//可以看出new String(...)过程开辟的空间没啥用,浪费了。

//我们知道,我们平时比较两个字符串的时候通常使用equals()方法,而equals()方法比较的是"值"是否相等,而没有比较"内存地址"是否相同。
// == 比较的则是 值是否相等 且 内存地址是否相同。

  

参考:【Java_基础】java中的常量池

猜你喜欢

转载自www.cnblogs.com/HelloHai/p/11754343.html