网站首页 > java教程 正文
1.常量池
1.1概念
常量池是 Java 虚拟机 (JVM) 中一个特殊的内存区域,用于存储编译期间生成的各种字面量和符号引用。它可以分为两种:
- 编译时常量池: 存在于 .class 文件中,包含了类名、方法名、字段名等信息。
====编译时常量池存在于 .class 文件中,使用 constant_pool 表结构存储。=====
// .class 文件结构
constant_pool {
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count - 1];
}
// 常量池信息结构
cp_info {
u1 tag;
u1 info[];
}
// 常量池信息类型
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
// ... 其他类型 ...
========= 示例 ==========
// Test.java
public class Test {
public static void main(String[] args) {
System.out.println("hello");
}
}
===== Test.class 文件中的常量池内容 =========
Constant pool:
#1 = Methodref #4.#11 // java/lang/System.out.println:(Ljava/lang/String;)V
#2 = Class #12 // Test
#3 = Utf8 main
#4 = Class #13 // java/lang/System
#5 = Utf8 out
#6 = Class #14 // java/io/PrintStream
#7 = Utf8 println:(Ljava/lang/String;)V
#8 = Utf8 (Ljava/lang/String;)V
#9 = Utf8 String
#10 = Utf8 args
#11 = NameAndType #7:#8 // println:(Ljava/lang/String;)V
#12 = Utf8 Test
#13 = Utf8 java/lang/System
#14 = Utf8 java/io/PrintStream
#15 = Utf8 hello
#16 = String #15 // hello
#1 是一个方法引用,指向 java.lang.System.out.println(String) 方法。
#15 是一个 Utf8 类型常量,存储字符串 "hello"。
#16 是一个 String 类型常量,引用了 #15 中存储的 "hello" 字符串。
- 运行时常量池: 存在于 JVM 的方法区中,包含了编译时常量池中的内容,以及运行时生成的常量。
String str1 = "hello";
String str2 = new String("hello");
String str3 = str1 + " world";
str1 的 "hello" 会被存储在 String 常量池中。
str2 的 "hello" 会在堆中创建一个新的 String 对象,不会被存储在 String 常量池中。
str3 的 "hello world" 会在堆中创建一个新的 String 对象,并存储在 String 常量池中。
注意:
String 常量池是运行时常量池的一部分,但它与其他类型常量的存储方式不同。
String 常量池中的对象是不可变的,即使使用 StringBuilder 或 StringBuffer 修改字符串,
也会创建一个新的 String 对象。
1.2常量池存储内容
- 字面量: 包括字符串字面量、基本类型常量 (如 1、2.0、true 等)。
- 符号引用: 指向类、方法、字段的引用,在类加载的时候会被解析为直接引用。
1.3常量池的作用
- 提高代码效率: 重复使用常量池中的内容,避免重复创建对象,节省内存空间。
- 支持动态加载: 运行时可以动态生成新的常量,并将其加入到常量池中。
1.4String常量池
String 常量池是运行时常量池的一个重要部分。当使用字符串字面量创建 String 对象时,JVM 会先在 String 常量池中查找是否存在相同的字符串对象。如果存在,则直接返回该对象;如果不存在,则创建一个新的 String 对象并将其加入 String 常量池。
装拆箱机制
2.1概念
Java 中的基本数据类型是值类型,而对象是引用类型。装箱是指将基本数据类型转换为对应的包装类对象,而拆箱是指将包装类对象转换为对应的基本数据类型。
2.2装箱
- 使用包装类的构造函数: Integer i = new Integer(10);
- 使用包装类的 valueOf() 方法: Integer i = Integer.valueOf(10);
2.3拆箱
- 使用包装类的 xxxValue() 方法: int i = Integer.intValue();
- 自动拆箱: 在需要基本数据类型的地方,会自动调用包装类的 xxxValue() 方法进行拆箱。
2.4装拆箱的原理
Java 编译器会将装箱和拆箱操作转换为相应的代码,例如:
- 装箱: Integer i = new Integer(10); 会被转换为 Integer i = Integer.valueOf(10);
- 拆箱: int i = Integer.intValue(); 会被转换为 int i = i.intValue();
2.5装拆箱的应用场景
- 自动装拆箱: Java 中提供了自动装拆箱机制,方便了开发人员使用。
- 泛型: 泛型中只能使用引用类型,所以需要将基本数据类型转换为包装类对象。
- 集合: 集合只能存储对象,所以需要将基本数据类型转换为包装类对象。
2.6装拆箱的性能问题
装拆箱操作会带来一定的性能损耗,因为需要创建和销毁对象。在需要频繁进行装拆箱操作的场景中,应该尽量避免使用自动装拆箱机制,可以使用基本数据类型来提高效率。
猜你喜欢
- 2024-10-07 VMware Workstation Pro 17 的安装详解
- 2024-10-07 redhat Linux 8.10 安装体验(redhat linux 7.2系统安装详细过程)
- 2024-10-07 VMware workstation Pro 17虚拟机安装AnoliOS 8.9系统教程
- 2024-10-07 redis2.8-windows版安装和redis命令知识
- 2024-10-07 Oracle Linux 8.10 安装体验(oracle linux7.7安装)
- 2024-10-07 Flink教程(万字图文全面详解)(flink 教程)
- 2024-10-07 Kafka的安装部署:构建高可用的消息队列系统
- 2024-10-07 Keil uVision 4.22a MDK版 安装教程(附安装包下载)
- 2024-10-07 完全免费Cubase8.0 软件图文安装步骤教程附安装包
- 2024-10-07 Java修炼终极指南:164 为modf()生成本地绑定
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)