看似简单的问题深入一下:
编译阶段、运行时,自动装箱 / 自动拆箱是发生在什么阶段?
语法糖:Java 平台为我们自动进行了一些转换,保证不同的写法在运行时等价,发生在编译阶段,也就是生成的字节码是一致的。
我在前面提到使用静态工厂方法 valueOf 会使用到缓存机制,那么自动装箱的时候,缓存机制起作用吗?
Integer.valueOf,自然能够得到缓存的好处啊。建议避免无意中的装箱、拆箱行为,尤其是在性能敏感的场合,创建 10 万个 Java 对象和 10 万个整数的开销可不是一个数量级的
为什么我们需要原始数据类型,Java 的对象似乎也很高效,应用中具体会产生哪些差异?
原始数据类型局限:原始数据类型和 Java 泛型并不能配合使用,Java 的泛型某种程度上可以算作伪泛型,它完全是一种编译期的技巧,Java 编译期会自动将类型转换为对应的特定类型,这就决定了使用泛型,必须保证相应类型可以转换为 Object。
无法高效地表达数据,也不便于表达复杂的数据结构,比如 vector 和 tuple。
阅读过 Integer 源码吗
Integer 的缓存范围虽然默认是 -128 到 127,实现在 IntegerCache 的静态初始化块里。根据需要调整的,JVM 提供了参数设置:-XX:AutoBoxCacheMax=N
对象对象的组成:
由三部分组成,对象头,对象实例,对齐填充。
其中对象头一般是十六个字节,包括两部分,第一部分有哈希码,锁状态标志,线程持有的锁,偏向线程id,gc分代年龄等。第二部分是类型指针,也就是对象指向它的类元数据指针,可以理解,对象指向它的类。
对象实例就是对象存储的真正有效信息,也是程序中定义各种类型的字段包括父类继承的和子类定义的,这部分的存储顺序会被虚拟机和代码中定义的顺序影响
第三部分对齐填充只是一个类似占位符的作用,因为内存的使用都会被填充为八字节的倍数。