1. 基本数据类型
1.1 基本类型并不是对象
大一统是很重要的,就像秦国统一六国,要搞车同轨、书同文、行同伦,统一的制度便于统一的管理。
但是Java却没有做到,虽然号称一切都是对象,但是实际上还有一些不属于对象的基本数据类型,他们就是非常出名的:
- byte
- short
- int
- long
- char
- float
- double
- boolean
虽说一切都是对象,但是尴尬如下,基本类型并不是对象。
public static void main(String[] args) {
Object obj = new Object();
String str = new String();
WrapperDemo wrapperDemo = new WrapperDemo();
int num = 1;
System.out.println(obj instanceof Object);// 输出true
System.out.println(str instanceof Object);// 输出true
System.out.println(wrapperDemo instanceof Object);// 输出true
System.out.println(num instanceof Object);// 报错 Incompatible conditional operand types int and Object
}
1.2 无法完成大一统操作
这样不好,如果不能提供一个最基础的抽象,那么势必有一些方法,没法同时兼容基本数据类型和引用数据类型。
下面的方法,就很尴尬了,因为无法支持基本数据类型,所以功能就像被阉割了。
/**
* 获取一切对象的类型名称
*/
public static String getObjectType(Object obj) {
return obj.getClass().getName();
}
2. 包装类
Java开发者也发现这个问题,所以提供了包装类,为8中基本类型定义了对应的引用类型。
基本类型 | 对应包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
有了包装类,我们就可以统一全部的数据类型了,当我定义属性、参数的时候,就可以有一个抽象的根基了。如下所示,一切都可以用对象来表示。
public static void main(String[] args) {
Object obj = new Object();
String str = new String();
WrapperDemo wrapperDemo = new WrapperDemo();
Integer num = 1;
System.out.println(obj instanceof Object);// 输出true
System.out.println(str instanceof Object);// 输出true
System.out.println(wrapperDemo instanceof Object);// 输出true
System.out.println(num instanceof Object);// 输出true
}
3. 自动装箱、拆箱
但是大家还是习惯于用int
这样的基本类型啊,谁闲着没事写Integer
呢,想必人很少吧。
没事,JDK1.5开始,提供了自动装箱、自动拆箱的功能。例如:
public static void main(String[] args) {
int a = 1;
Integer b = a;// 自动装箱:基本类型的变量-->包装类变量
int c = b;// 自动拆箱:包装类变量-->基本类型变量
System.out.println("a:" + a + " b:" + b + " c:" + c);// 输出 a:1 b:1 c:1
}
看着是不是没啥意思,其实这就实现了向前的自动兼容。看下面的例子:
public class WrapperDemo {
public static void main(String[] args) {
String str = "abc";
Integer num1 = 200;
int num2 = 100;
System.out.println(getObjectType(str));//输出java.lang.String
System.out.println(getObjectType(num1));//输出java.lang.Integer
System.out.println(getObjectType(num2));//输出java.lang.Integer
}
/**
* 获取一切对象的类型名称
*/
public static String getObjectType(Object obj) {
return obj.getClass().getName();
}
}
str和num1的类型输出很好理解,num2为啥会输出Integer呢。
num2会自动装箱成Integer类型,然后Object类型又是所有类型的基类,所以可以接受Integer类型的参数,所以可以打印出java.lang.Integer
。
4. 小结
通过包装类,提供了全局统一视角,让一切皆为对象成为现实。
通过自动装箱、拆箱,实现了对原有基本类型的向前兼容,无缝衔接。
这是思想的进步啊,通过更加彻底的抽象,可以提供更加普适的操作。