Java是面向对象的语言,但并不是“纯面向对象”的,因为我们经常用到的基本数据类型就不是对象。但是我们在实际应用中经常需要将基本数据转化为对象,以便于操作。比如:将基本数据类型存储到Object[]数组或集合操作中等等。
Object o = {1024,"张三"};
其中的1024在我们现在看来是一个基本数据类型int,但是数组是Object类型的,int不是一个Object的子类,它是基本数据类型的,其实这中间有个装箱的过程,将int包装成一个对象
基本数据类型
|
包装类
|
byte
|
Byte
|
boolean
|
Boolean
|
short
|
Short
|
char
|
Character
|
int
|
Integer
|
long
|
Long
|
float
|
Float
|
double
|
Double
|
包装类Integer、Byte、Double等都继承了一个类Number,里面提供了各种方法,例如ValueOf等等
1 package com.testwrappedclass; 2 public class TestWrappedClass { 3 public static void main(String[] args) { 4 //基本类型转为包装类 5 int a =3; 6 // Integer a_integer = new Integer(a);//在version9是官方不再建议这样书写 7 Integer a_integer = Integer.valueOf(a); 8 double b = 4.0; 9 Double b_double = Double.valueOf(b); 10 11 //包装类转成基本类型 12 int a_int = a_integer.intValue(); 13 double b_doub = b_double.doubleValue(); 14 15 //字符串转为包装类 16 String s="2315"; 17 Integer s2int = Integer.valueOf(s);//其实是调用了parseInt(String s)方法 18 19 //包装类转为字符串 20 String string = s2int.toString(); 21 } 22 }
也就是说,转为包装类(Integer/Double/....)都用.valueOf()方法,转为基本类型(int/double/...)用int/double/xxxValue(),转为字符串类型用toString()
自动拆箱与装箱
自动拆箱与装箱是由编译器compiler完成的,自动拆箱即由包装类"直接"转为基本类型;自动装箱即由基本类型"直接"转为包装类。如:
//自动拆箱 Integer w = Integer.valueOf(3); int a =w;//实际上,编译器会自动加上w.intValue()方法 //自动装箱 Integer r = a;//实际上,编译器会自动加上r.valueOf(a)方法
再看下面的这个例子:
Integer p =null; int c =p;
若运行,编译器会报
Exception in thread "main" java.lang.NullPointerException
NullPointerException 错误是说企图调用一个空对象中的方法。但是我们没看到有调用p的方法啊?其实是有的,自动拆箱调用了Integer的intValue()方法。
包装类的缓冲池问题
//包装类中的缓冲池的问题 Integer int3 = Integer.valueOf(1234); Integer int4 = Integer.valueOf(1234); 😀System.out.println(int3==int4); 🐶System.out.println(int3.equals(int4)); Integer int1 = Integer.valueOf(-128); Integer int2 = Integer.valueOf(-128); 😘System.out.println(int1==int2); 🐷System.out.println(int1.equals(int2)); ##########输出结果################# false true true true
在😀处:因为int3和int4是两个不同的对象,所以输出为false
在🐶处:因为int3和int4中的内容相等,所以输出为true
在😘处:为啥int1和int2是不同的对象,但是输出为true呢??原来在包装类中的valueOf方法有这样一个机制,先看下它的源代码:
@HotSpotIntrinsicCandidate public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high)//IntegerCache.low=-128,IntegerCache.high=127 return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 而IntegerCache是这样的: 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; 。。。。。
原来,我们在使用valueOf方法时,会自动创建一个Integer类型的数组cache,cache数组中的每个对象是-128~127各个数形成的包装类。如果我们的整型包装类对象的值在-128~127之间,则不再创建新的对象,而是直接到cache数组找这个对象。如上例int1和int2都是-128值,那它们对应的对象就是cache数组中值为-128的对象,所以为true
来源:https://www.cnblogs.com/Kundalini/p/11707962.html