一、引言
1.概述
对于基本数据类型,在变量中记录的是真实的数据值。
而对于基本数据类型的包装类, 本质是创建了一个对象,对象当中记录对应的数据值。
即:包装类就是用一个对象,把基本数据类型给包起来。
包装类对应的规则如下:(除了char和int其他全部首字母大写)
2.原因
question:为什么要创造包装类?直接用基本数据类型不行吗?
对于这样的一个函数,形参是一个Object 类型的对象。
由于java 多态的存在, 我可以 传入任何 类的对象,都没有问题。
但是对于基本数据类型,是不能够作为参数传递到这个方法中的,因为基本数据类型不是类,这就会导致一个局限性。
其次,在集合中也是不能存储基本数据类型的,只能够存储对象。
二、方法
1.获取Integer对象
public class Demo1 {
public static void main(String[] args) {
//1.利用构造方法获取Integer对象(JDK5之前)
Integer i1=new Integer(1);
Integer i2=new Integer("1");
System.out.println(i1);
System.out.println(i2);
//2.利用静态方法获取Integer对象(JDK5之前)
Integer i3 = Integer.valueOf(123);
Integer i4 = Integer.valueOf("123");
Integer i5 = Integer.valueOf("123",8);//8进制的123 --> 83(十进制)
System.out.println(i3);
System.out.println(i4);
System.out.println(i5);//83
}
}
细节:
上述两种方法(new 和 valueOf )都是JDK5之前所使用的方法,现在均以淘汰。
**************************************************************************************************************
question:两种方法有什么区别呢?
首先,对于下列代码,结果会是什么呢?
public class Demo2 {
public static void main(String[] args) {
Integer i1 = Integer.valueOf(127);
Integer i2 = Integer.valueOf(127);
System.out.println(i1 == i2);
Integer i3 = Integer.valueOf(128);
Integer i4 = Integer.valueOf(128);
System.out.println(i3 == i4);
Integer i5 = new Integer(127);
Integer i6 = new Integer(127);
System.out.println(i5 == i6);
Integer i7 = new Integer(128);
Integer i8 = new Integer(128);
System.out.println(i7 == i8);
}
}
运行结果:
我们知道,只要是new 出来的对象,都是在堆中开辟了一块新的空间,所以地址值不相等,最后两个都是false。
通过查看valueOf 的源码可以发现,它在底层做了一定的优化:
因为在实际开发中,-128 ~ 127 之间的数据,用的最频繁。
如果每次都通过 new 来创建对象,太消耗内存了。
所以 valueOf 提前将这个范围内的每一个数据都创建好了对象,如果用到了,直接返回,就不会创建新的对象了。
由于第一个创建的对象 i1 和 i2 的数据都是127,是直接返回已经创建好的对象,所以地址值相等
而 i3 和 i4 的数据都是128,不在这个范围内,会重新创建新的对象,所以地址值不相等。
2.计算
由于 包装类也是一个对象,对象之间是不能直接相加减进行计算的。
在以前,包装类的计算方式:
① 把对象进行拆箱,变回基本数据类型
② 相加
③ 把得到的结果在进行装箱(再变回包装类)
public class AddDemo {
public static void main(String[] args) {
Integer i1 = new Integer(1);
Integer i2 = new Integer(2);
// ① 拆箱
int x1 = i1.intValue();
int x2 = i2.intValue();
// ② 相加
int result = x1 + x2;
//③ 装箱
Integer i3 = new Integer(result);
System.out.println(i3);//3
}
}
但这种方法过于麻烦,所以在 JDK5 时,提出了一个新的机制:自动装箱 和 自动拆箱。
public class AddDemo2 {
public static void main(String[] args) {
//自动装箱:把 基本数据类型 自动变成其对应的 包装类
Integer i1 = 1;
Integer i2 = 2;
//自动拆箱:把 包装类 自动变成其对应的 基本数据类型
int result = i1 + i2;
System.out.println(result);
}
}
细节:
① 自动装箱时,会在底层自动调用 valueOf 方法得到一个 Integer 对象,但这个步骤无需手动操作。
② JDK5 以后,int 和 Integer 可以看作是同一个东西,因为在内部两者可以自动转化。
扩展:
ArrayList<Integer> list = new ArrayList<>();
int num = 10;
list.add(num);
这里在添加数据时也触发了一个自动装箱,将 int 型的num 转换成了 Integer 对象,再放入集合中。
相当于 list.add(Integer.valueOf(num));
3.成员方法
public class Demo3 {
public static void main(String[] args) {
//1.整数转成二进制
String str1 = Integer.toBinaryString(100);
System.out.println(str1);//1100100 --> 64 + 32 + 4 = 100
System.out.println("----------------------");
//2.整数转成八进制
String str2 = Integer.toOctalString(100);
System.out.println(str2);//144 --> 64 + 4*8 + 4 = 100
System.out.println("----------------------");
//3.整数转成十六进制
String str3 = Integer.toHexString(100);
System.out.println(str3);//64 --> 6*16 + 4 = 100
System.out.println("----------------------");
//4.将字符串类型的整数转换成int类型的整数
int i = Integer.parseInt("123");
System.out.println(i + 1);//124
}
}
细节:
① java 是一门强类型语言:即每种数据在java种都必须有各自的数据类型。不同数据类型之间无法直接计算,必须通过转换数据类型。
② 在类型转换时,parseInt 方法的参数种只能是数字,不能是其他,否则报错。( "abc" 无法转成int )
③ 8 种包装类当中,除了Charater 都有对应的 parseXxx的方法,进行类型转换。