包装类型

引言:包装类型

包装类型

java的数据类型分为两类:一类是基本类型:int byte short long float double boolean char
一类是引用类型:类、接口、数组

Java是一个面向对象的语言,有时在对于基本类型操作很不方便,所以引入了包装类型,给基本类型加上了方法和类型

为什么要叫包装类型?
我是这么理解的:基本类型就像是芝麻粒,为了吃它或者是榨油,我们只有将它装起来才能更好的利用它。


以下都用int型来举例

创建一个包装类型对象

总共有三种方法来创建一个包装类型

1
2
3
Integer i1 = new Integer(1);
Integer i2 = Integer.valueOf(2);
Integer i3 = Integer.valueOf("3");

第一个是Integer类的构造方法

第二个和第三个方法是Integer类的静态方法

自动装箱、自动拆箱

我们经常见到的

1
2
Integer n = 100;//编译器自动使用Integer.valueOf(int)
int x = n; // 编译器自动使用Integer.intValue()

其实是编译器帮我们完成了这项工作,在我们编译的时候,编译器仍然会把这个句子翻译成valueOf()的方法,从基本类型到包装类型这个过程叫自动装箱(Auto Boxing),同理从包装类型到基本类型有自动拆箱

底层

发现很有意思的一件事

1
2
3
4
5
6
7
8
9
10
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
Integer i3 = 1;
Integer i4 = 1;
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i1==i2);//false
System.out.println(i1==i3);//false
System.out.println(i3==i4);//true
System.out.println(i5==i6);//false

前两个很好理解,new方法创建的实例会放在堆中,是不一样的实例

但是后两个一个true一个false

这是为什么呢?

不变类

观察Integer底层代码,会发现其实Integer对象是不可以改变的

1
2
3
public final class Integer {
private final int value;
}

但是为了节省内存,Java将-128 ~ 127的所有数都返回相同的实例,这就是i3和i4相同但是i5和i6不同的原因

**所以我们在创建Integer类的时候,最好使用Integer.valueOf();(或者直接自动装箱)**这个构造方法,因为new方法构建的实例对象是一个“新”的实例,而这个方法直接从IntegerCache中获取

包装类比较

包装类是一个类,我们不能把它再看做一个基本类型了,所以我们需要使用equals方法,使用==就算对了,也只是碰巧使用的数字恰好在-128~127之间而已

所以我们进行比较依然要使用equals()方法

其他常见方法

进制转换

包装类可以轻松的进制转换

1
2
3
Integer i1 = new Integer(59);
System.out.println(Integer.toBinaryString(i1));//111011
System.out.println(Integer.toHexString(i1));//3b

获取常量

1
2
3
4
5
6
7
8
9
// boolean只有两个值true/false,其包装类型只需要引用Boolean提供的静态字段:
Boolean t = Boolean.TRUE;
Boolean f = Boolean.FALSE;
// int可表示的最大/最小值:
int max = Integer.MAX_VALUE; // 2147483647
int min = Integer.MIN_VALUE; // -2147483648
// long类型占用的bit和byte数量:
int sizeOfLong = Long.SIZE; // 64 (bits)
int bytesOfLong = Long.BYTES; // 8 (bytes)

转换各类

所有的整数和浮点数的包装类型都继承自Number,因此,可以非常方便地直接通过包装类型获取各种基本类型:

1
2
3
4
5
6
7
8
// 向上转型为Number:
Number num = new Integer(999);
// 获取byte, int, long, float, double:
byte b = num.byteValue();
int n = num.intValue();
long ln = num.longValue();
float f = num.floatValue();
double d = num.doubleValue();

处理无符号整型

Java中都是有符号的,没有无符号的整型

而c中对此非常认真,有符号也有无符号

无符号整型和有符号整型的转换在Java中就需要借助包装类型的静态方法完成。

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
byte x = -1;
byte y = 127;
System.out.println(Byte.toUnsignedInt(x)); // 255
System.out.println(Byte.toUnsignedInt(y)); // 127
}
}

因为byte的-1的二进制表示是1111 1111,以无符号整型转换后的int就是255。

类似的,可以把一个short按unsigned转换为int,把一个int按unsigned转换为long。

参考资料:
简书:@我没有三颗心脏以及廖雪峰官方网站