数据类型
包装类型(八大基本类型)
- 整型(
int
):用于表示整数,范围为-2^31 到 2^31-1(32位)。 - 长整型(
long
):用于表示更大范围的整数,范围为-2^63 到 2^63-1(64位)。 - 浮点型(
float
):用于表示单精度浮点数,遵循IEEE 754标准。 - 双精度浮点型(
double
):用于表示双精度浮点数,也遵循IEEE 754标准,精度高于float
。 - 字符型(
char
):用于表示单个字符,范围为0 到 65535(16位)。 - 布尔型(
boolean
):只有两个可能的值:true
和false
。 - 字节型(
byte
):用于表示较小的整数,范围为-128 到 127(8位)。 - 短整型(
short
):用于表示较小范围的整数,范围为-32768 到 32767(16位)。
基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。
Java中的基本类型都有对应的包装类型(也称为包装类或包装器),它们允许基本类型被当作对象来使用。以下是基本类型与其对应的包装类型的对应关系:
int
对应Integer
long
对应Long
float
对应Float
double
对应Double
char
对应Character
boolean
对应Boolean
byte
对应Byte
short
对应Short
自动装箱(Autoboxing)和自动拆箱(Unboxing)是Java 5引入的特性,它们允许在基本类型和对应的包装类型之间无缝转换:
- 自动装箱:将基本类型转换为对应的包装类型对象。
- 自动拆箱:将包装类型对象转换为对应的基本类型。
例如:
Integer integerObject = 10; // 自动装箱,将int转换为Integer对象
int intValue = integerObject; // 自动拆箱,将Integer对象转换为int
自动装箱和拆箱使得代码更加简洁,特别是在使用集合类(如List<Integer>
)时,可以方便地使用基本类型的值,而不需要显式地创建包装类对象。
然而,过度使用自动装箱和拆箱可能会对性能产生负面影响,因为每次装箱和拆箱都会创建新的包装类对象,这可能导致不必要的对象创建和垃圾收集。在性能敏感的应用程序中,应当谨慎使用。
缓存池
new Integer(123)
和 Integer.valueOf(123)
都是创建了一个新的 Integer
对象,但它们之间存在一些关键的区别:
- 缓存机制:
Integer.valueOf(int i)
方法在内部使用了缓存机制。根据Java的自动装箱规范,Integer.valueOf()
方法会缓存从-128
到127
范围内的Integer
对象。因此,当你多次调用valueOf()
方法并传入这个范围内的值时,它将始终返回相同的Integer
对象实例。new Integer(123)
不受缓存机制的影响,每次都会创建一个新的Integer
对象实例。
- 性能:
- 由于
valueOf()
方法的缓存机制,如果你在程序中多次使用相同的整数值,使用valueOf()
会比使用new Integer()
更加高效,因为它减少了对象的创建数量,从而减少了垃圾收集的开销。
- 由于
- 内存使用:
- 使用
valueOf()
方法时,由于缓存的存在,对于在缓存范围内的整数值,内存使用量会更低,因为多个引用实际上指向的是同一个对象。
- 使用
- API 设计:
valueOf()
是Integer
类的一个static
方法,它被明确设计用于返回一个特定的Integer
对象,考虑到了缓存优化。new Integer(123)
是直接使用构造器创建新对象的一般方式,没有考虑到缓存优化。
- 使用场景:
- 当你需要一个特定的新
Integer
对象实例时,可以使用new Integer(123)
。 - 当你需要一个
Integer
对象,并且该值可能在-128
到127
的范围内,为了性能考虑,应该使用Integer.valueOf(123)
。
- 当你需要一个特定的新
在 Java 8 中,Integer 缓存池的大小默认为 -128~127。
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
编译器会在缓冲池范围内的基本类型自动装箱过程调用 valueOf() 方法,因此多个 Integer 实例使用自动装箱来创建并且值相同,那么就会引用相同的对象。
Integer m = 123;
Integer n = 123;
System.out.println(m == n); // true
如果在缓冲池之外:
Integer m = 323;
Integer n = 323;
System.out.println(m == n); // false