Java里的包装类型
其实也就那么几个
基础数据类型&包装类型
和面向过程的编程不同,Java里,一切皆对象,但是就有那么一些例外,就是常见的int
,char
,boolean
,float
,double
,byte
,short
,long
,八大基础数据类型,基础类型,没他不行,但是和其他对象的操作又不一样,于是Java对基础数据类型进行了上层封装,也就是所谓的包装类型
基础数据类型 |
包装类型 |
int |
Integer |
char |
Character |
boolean |
Boolean |
short |
Short |
long |
Long |
byte |
Byte |
float |
Float |
double |
Double |
包装类型中,除了int
和char
,其余的包装类型仅仅是基础类型首字母大写,包装类型提供了面向对象的性质,可以计算HashCode,使用equals进行对比等,既然是把它当作对象,肯定和基础数据类型有区别
public class WrapprTest {
public static void main(String[] args) {
int num = 1;
Integer a = new Integer(num);
Integer b = new Integer(num);
System.out.println("a == b:"+(a == b));
System.out.println("a != b:"+(a != b));
System.out.println("a > b:"+(a > b));
System.out.println("a < b:"+(a < b));
System.out.println("a >= b:"+(a >= b));
System.out.println("a <= b:"+(a <= b));
}
}
结果如下:
a == b:false
a != b:true
a > b:false
a < b:false
a >= b:true
a <= b:true
Process finished with exit code 0
结果表明,当使用==
和!=
的时候,直接比较的是对象的地址,两个对象地址不同所以返回的是false,当使用>
,<
,>=
,<=
的时候,会直接比较两个对象对应的值,至于equals
函数
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
直接比较的是int的值,所以返回true
装箱与拆箱
// 装箱,将基础数据类型封装成包装类型
Integer i = new Integer(1);
// 拆箱,将包装类型包装的基础类型取出
int num = i.intValue();
JDK1.5之后就有了自动装箱和拆箱
Integer i = 1;
int num = i;
自动装箱过程中的内存复用
看一段代码
public class WrapprTest {
public static void main(String[] args) {
int num1 = 100;
int num2 = 200;
Integer a = num1;
Integer b = num1;
System.out.println(a == b);
a = num2;
b = num2;
System.out.println(a == b);
}
}
==
直接比较的是对象在内存中的地址,结果是true和false
要解释这个问题,首先要知道,自动装箱是基于valueOf()
函数实现的,瞅一瞅它的实现
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我们发现了一层缓存,当给定的i值在缓存的区间里的时候,会直接从缓存中拿到这个对象,否则就去新建一个对象,缓存中都是一些常用的对象,接下来看一下low
和high
分别是多少
private static class IntegerCache {
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;
}
private IntegerCache() {}
}
这里看来,low
永远是-128,但是high
的值可以自己设置,最小是128,最大是Integer.MAX_VALUE - (-low) -1
# 设置整数的缓存复用范围
java -D java.lang.Integer.IntegerCache.high=200 CLASSNAMEE
# 设置自动装箱的缓存复用
java -XX:XX:AutoBoxCacheMax=200 CLASSNAME