1. 引出包装类
问题1: 在面向对象中,一切皆对象,给你一个整数常量,但是,int age=17;请问这age代码哪里有对象。没有对象,此时有矛盾。
问题2: 给你一个复杂的十进制数据,请你迅速给我转成二进制,八进制,十六进制,算法太麻烦了。
问题3: 使用double类型表示学生的考试成绩,但是,怎么表示一个人缺考和考试得0分。
上述问题::是因为基本数据类型缺少对象,如果需要对象,必须先有类!
此时,我们可以编写为每一个基本类型编写一个基本类型和写一个对应的包装类,类中包含了基本类型的一个值。
模拟Java中int类型的包装类
class IntWapper
{
private final int value;
IntWapper(int value){
this.value = value;
}
public void method(){
System.out.println("Int包装类的一些相关算法");
}
}
class WapperDemo
{
public static void main(String[] args)
{
IntWapper value1 = null; // 相当于没有对象
IntWapper value2 = new IntWapper(1);// 创建对象,值为1
}
}
2. 包装类
八大基本数据类型对应的包装类,int的包装类为Integer,char的包装类为Character,除了这两个以外,其他的六个基本数据类型对应的包装类名都是首字母大写。
八大基本数据类型的包装类都使用 final 修饰,都是最终类,仅能被使用,都不能被继承。
3. 装箱和拆箱
装箱: 把基本类型数据转成对应的包装类对象。
class IntegerDemo
{
public static void main(String[] args)
{
// 装箱操作,写法1:
Integer num1 = new Integer(1);
// 装箱操作,写法2:
Integer num2 = Integer.valueOf(1); // 推荐这种写法,带有缓存
}
}
拆箱: 把包装类对象转成对应的基本数据类型变量。
class IntegerDemo
{
public static void main(String[] args)
{
// 装箱操作
Integer num1 = new Integer(1);
// 拆箱操作
int num2 = num1.intValue();
}
}
我们打印Integer对象看下是什么?
class IntegerDemo
{
public static void main(String[] args)
{
// 装箱操作
Integer num = new Integer(1);
System.out.println(num);
}
}
---------- 运行java ----------
1
输出完成 (耗时 0 秒) - 正常终止
根据之前学习的知识,打印对象时应该得到的是一个对象的hashcode值,但是我们通过打印Integer对象内容发现,结果竟然是构建对象时赋的值。显然,这说明这Integer类中覆盖了Object类的toString方法。 通过查看Integer源代码,果然如此:
4. 自动装箱和拆箱
在Java的集合框架中,只能存储对象,不能存储基本类型值。每次存储到集合中的基本数据都得手动来装箱.。这样太麻烦了!从Java5开始提供了的自动装箱(Autoboxing)和自动拆箱(AutoUnboxing)功能 。
自动装箱: 可把一个基本类型变量直接赋给对应的包装类变量。
自动拆箱: 允许把包装类对象直接赋给对应的基本数据类型变量。
class IntegerDemo
{
public static void main(String[] args)
{
// 自动装箱
Integer num = 17; // 简单粗暴,就像定义基本数据类型一样!
// 自动拆箱
int newNum; // 定义基本数据类型newNum
newNum = num; // 直接将Integer类型数据赋值给基本数据类型
}
}
将上述代码进行反编译:
通过反编译:我们可以看到在编译时,还是进行了手动装箱(方式2)和手动拆箱操作
因此,自动装箱和拆箱,也是一个语法糖/编译器级别新特性。在底层依然是手动装箱和拆箱操作。但是,装箱操作使用的是Integer.valueOf的方式,而不是直接new Integer。
补充:
switch支持的数据类型:
byte,short,char,int,也支持对应的包装类.。为什么?
因为底层,switch中会对包装类做手动拆箱操作。
解释Object obj = 17;其实这行代码包含两个知识点:
(1)自动装箱: Integer i = 17;
(2)引用的自动类型转换,把子类对象赋给父类变量: Object obj = i;
Object可以接受一切数据类型的值。
Object数据:Object[] 该数组可以装一切数据类型。
Object[] arr = {"A",12,3.14,true};