1、 什么是包装类
包装类就是Java基本数据类型的对象表示形式。其中包括基本数据类型byte, char, short, int, long, float, double, boolean。
2、有哪些包装类
- byte <====> java.lang.Byte
- char <====> java.lang.Character
- short <====> java.lang.Short
- int <====> java.lang.Integer
- long <====> java.lang.Long
- float <====> java.lang.Float
- double <====> java.lang.Double
- boolean <====> java.lang.Boolean
3、为什么要用包装类
- Java是一门面向对象语言,在进行面向对象开发时,有些方法声明必须传入对象,而基本类型值不具备对象特性,为了基本类型具有对象特征,这时就出现了包装类
- 泛型不能使用基本类型,例如List<T>, Set<T>, Map<K, V>
4、使用包装类有哪些值得注意的地方
-
byte <====> java.lang.Byte
private static class ByteCache { private ByteCache(){} // byte 占一个字节8bit,有符号,取值范围 -2^7 ~ 2^7-1 static final Byte cache[] = new Byte[-(-128) + 127 + 1]; static { // 初始化Byte缓存 for(int i = 0; i < cache.length; i++) cache[i] = new Byte((byte)(i - 128)); } } public static Byte valueOf(byte b) { final int offset = 128; return ByteCache.cache[(int)b + offset]; }
无论short取何值, 都从缓存中的获取。即
Byte a = 1; Byte b = 1; System.out.println(a == b); // print true
-
char <====> java.lang.Character
private static class CharacterCache { private CharacterCache(){} static final Character cache[] = new Character[127 + 1]; static { // 缓存标准ASCII表 for (int i = 0; i < cache.length; i++) cache[i] = new Character((char)i); } } public static Character valueOf(char c) { if (c <= 127) { // must cache return CharacterCache.cache[(int)c]; } return new Character(c); }
当char取值在0~127范围内,取缓存中的,不在次范围内的在java堆中创建新对象。即
Character a = 'a'; Character b = 'a'; System.out.println(a == b); // print trueni Character c = '你'; Character d = '你'; System.out.println(c == d); // print false
-
short <====> java.lang.Short
private static class ShortCache { private ShortCache(){} static final Short cache[] = new Short[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Short((short)(i - 128)); } } public static Short valueOf(short s) { final int offset = 128; int sAsInt = s; if (sAsInt >= -128 && sAsInt <= 127) { // must cache return ShortCache.cache[sAsInt + offset]; } return new Short(s); }
当short取值在-128~127范围内,取缓存中的,不在次范围内的在java堆中创建新对象。即
Short a = 1; Short b = 1; System.out.println(a == b); // print true Short c = 256; Short d = 256; System.out.println(c == d); // print false
-
int <====> java.lang.Integer
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() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
默认,当integer取值-128~127范围内时,去缓存中的,不在此范围内的在java堆中创建新对象。
Integer最大范围可以通过设置参数java.lang.Integer.IntegerCache.high改变
即Integer a = 1; Integer b = 1; System.out.println(a == b); // print true Integer c = 256; Integer d = 256; System.out.println(c == d); // print false java -Djava.lang.Integer.IntegerCache.high=256 // print true
-
long <====> java.lang.Long
private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 1shi28); } } public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); }
默认,当integer取值-128~127范围内时,去缓存中的,不在此范围内的在java堆中创建新对象。
即Long a = 1L; Long b = 1L; System.out.println(a == b); // print true Long c = 256L; Long d = 256L; System.out.println(c == d); // print false
-
float <====> java.lang.Float
public static Float valueOf(float f) { return new Float(f); }
无论float什么取值都从java堆中新建对象,即
shiFloat a = 1.0f; Float b = 1.0f; System.out.println(a == b); // print false
-
double <====> java.lang.Double
public static Double valueOf(double d) { return new Double(d); }
无论double什么取值都从java堆中新建对象,即
Double a = 1.0; Double b = 1.0; System.out.println(a == b); // print false
为什么float和double都不缓存值?---->因为float,dobule都是精度值,区间内存在无限可取值,缓存无意义
-
boolean <====> java.lang.Boolean
Integer a = Integer.valueOf(1);public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
boolean 只有两种取值选择,即true or false; 则他们取值总是相等。
当对象直接通过new创建,将不会发生装箱,直接在java堆中创建。
5、什么情况发生自动拆箱装箱
-
赋值
Integer a = 1; int b = a; //编译后按照以下执行 Integer a = Integer.valueOf(1); int b = a.intValue();
-
运算
Integer a = 1; Integer b = 1; Integer c = a+b; //编译后按照以下执行 Integer a = Integer.valueOf(1); Integer b = Integer.valueOf(1); Integer c = Integer.valueOf(a.intValue() + b.intValue());
-
比较
Integer a = 1; int b = 2; System.out.println(a == b); //编译后按照以下执行 Integer a = Integer.valueOf(1); int b = 2; System.out.println(a.intValue() == b);
注意同是Integer类型之间的比较不会拆箱
-
方法调用
Integer a = 1; System.out.println(a.compareTo(2)); //编译后按照以下执行 Integer a = Integer.valueOf(1); System.out.println(a.compareTo(Integer.valueOf(2)));
网友评论