社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
基本类型 | 大小 | 数值范围 | 默认值 | 包装类型 |
---|---|---|---|---|
boolean | ^ | true,false | false | Boolean |
byte | 8bit | -2^7 – 2^7-1 | 0 | Byte |
char | 16bit | u0000 – uffff | u0000 | Character |
short | 16bit | -2^15 – 2^15-1 | 0 | Short |
int | 32bit | -2^31 – 2^31-1 | 0 | Integer |
long | 64bit | -2^63 – 2^63-1 | 0 | Long |
float | 32bit | IEEE 754 | 0.0f | Float |
double | 64bit | IEEE 754 | 0.0d | Double |
void | ^ | ^ | ^ | Void |
基本类型只有值,而装箱基本类型则具有与它们的值不同的同一性。换句话说,对装箱基本类型运用 == 操作符几乎总是错的
基本类型只有功能完备的值,而装箱基本类型除了它对应基本类型的所有功能值外,还有一个非功能值 null,这导致了对于包装基本类型进行拆箱操作后所进行的操作存在 NPE 的风险
基本类型更加省空间和时间,如果对包装类型进行频繁的装箱和拆箱操作会影响性能
//before autoboxing
Integer iObject = Integer.valueOf(3);
int iPrimitive = iObject.intValue()
//after java5
Integer iObject = 3; //autobxing - primitive to wrapper conversion
int iPrimitive = iObject; //unboxing - object to primitive conversion
public static Integer show(Integer iParam){
System.out.println("autoboxing example - method invocation i: " + iParam);
return iParam;
}
//autoboxing and unboxing in method invocation
show(3); //autoboxing
int result = show(3); //unboxing because return type of method is Integer
long t = System.currentTimeMillis();
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms");
total:2305843005992468481
processing time: 63556 ms
long t = System.currentTimeMillis();
long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms");
total:2305843005992468481
processing time: 12229 ms
sum = sum.longValue() + i;
Long sum = new Long(sum);
说明:包含在包装器中的内容不会改变。即Long对象是不可变的
public void test(int num){
System.out.println("method with primitive argument");
}
public void test(Integer num){
System.out.println("method with wrapper argument");
}
//calling overloaded method
AutoboxingTest autoTest = new AutoboxingTest();
int value = 3;
autoTest.test(value); //no autoboxing
Integer iValue = value;
autoTest.test(iValue); //no autoboxing
method with primitive argument
method with wrapper argument
public class AutoboxingTest {
public static void main(String args[]) {
// Example 1: == comparison pure primitive – no autoboxing
int i1 = 1;
int i2 = 1;
System.out.println("i1==i2 : " + (i1 == i2)); // true
// Example 2: equality operator mixing object and primitive
Integer num1 = 1; // autoboxing
int num2 = 1;
System.out.println("num1 == num2 : " + (num1 == num2)); // true
// Example 3: special case - arises due to autoboxing in Java
Integer obj1 = 1; // autoboxing will call Integer.valueOf()
Integer obj2 = 1; // same call to Integer.valueOf() will return same cached Object
System.out.println("obj1 == obj2 : " + (obj1 == obj2)); // true
// Example 4: equality operator - pure object comparison
Integer one = new Integer(1); // no autoboxing
Integer anotherOne = new Integer(1);
System.out.println("one == anotherOne : " + (one == anotherOne)); // false
}
}
i1==i2 : true
num1 == num2 : true
obj1 == obj2 : true
one == anotherOne : false
值得注意的是,在Example 2中,比较是一个对象和一个原始值,出现这种情况比较的应该是对象的值
让人感到困惑的Example 3,在一开始我们说过,”==”用于对象间的比较时,比较的是它们的引用,那么为什么obj1 == obj2返回的结果却是true?这是一种极端情况,处于节省内存的考虑,JVM会缓存-128到127的Integer对象。也就是说,在创建obj1对象时,会进行自动装箱操作,并且将其对象保存至缓存中,在创建obj2对象时,同样会进行自动装箱操作,然后在缓存中查找是否有相同值的对象,如果有,那么obj2对象就会指向obj1对象。obj1和obj2实际上是同一个对象。所以使用”==”比较返回true
而Example 4,是通过使用构造器来创建对象的,而没有发生自动装箱操作,不会执行缓存策略,故one和anotherOne是指向不同的引用的
说明:这种 Integer 缓存策略仅在自动装箱(autoboxing)的时候有用,使用构造器创建的 Integer 对象不能被缓存
private static Integer count;
//NullPointerException on unboxing
if( count <= 0){
System.out.println("Count is not started yet");
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!