1. java是类型的语言
public class Demo{
public static void main(String[] args){
int a = 10;
float b = 10.0f;
Cat cat = new Cat();
a = b;
a = cat;
}
}
在这个地方我们可以看到我们定义了几个变量,变量的基本赋值并没有什么问题,但是后边我们让a=b;a=cat;
却不能这样赋值,这是为什么呢?
可能有同学知道JAVA是强类型的语言,可是什么是强类型呢?
强类型的语言本质其实来自于数据在内存当中的存储。
我们知道JAVA有8种基本数据类型和三种引用数据类型。
比如int在类型在内存当中分配是1个符号位,31位数值位。
float在内存当中分配是1个符号位,8位阶位和23位的数值位。
那么我们如果想让一个float类型的数据装载到int类型当中,显然是不行的。
2. 那有没有违反我们的常识的呢?
从上面的图当中我们看到了一个不寻常的现象,就是一个int类型的值赋给了对象类型的变量。而且还成功了,那么这是为什么呢?
3. JAVA的万物皆对象
面向对象中,“一切皆对象”,但基本数据类型的数据不太符合这一理念,基本数据类型不是对象,所以JAVA设计出来了一个包装类。
我们知道以上代码的执行过程中,最开始是一个叫javac的编译器,将.java文件编译成为.class文件。在这个过程当中,我们写的程序:
Interger b = 10;
//会被编译成 Interger b = Interger.valueof(10); ---->自动装箱
int a = b;
//会被编译成 int a = b.intValue(); ---->自动拆箱
自动装箱:将基本数据类型自动转换为对应的包装类对象的过程。
自动拆箱:将包装类对象自动转换为对应的基本数据类型的过程。
4. 128陷阱
public static void main(String[] args) {
Integer a1 = 10;
Integer a2 = 10;
System.out.println(a1 == a2);
// == 比较的是地址是否相同
Integer a3 = 1000;
Integer a4 = 1000;
System.out.println(a3 == a4);
}
输出结果为:
答案就在Integer的value0f()方当中,我们将数值在-128-127之间的数值都存储在有一个Cache数组当中,该数组相当于一个缓存。
- 数据-128~127之间直接返回该值在数组当中的地址,所以在-128~127之间的数值用 == 进行比较是相等的。
- 而不在这个区间的数,需要新开辟一个内存空间,所以不相等。
5. 示例
public static void main(String[] args){
int a = 10;
int b = 10;
Integer a1 = 10;
Integer b1 = 10;
Integer a2 = new Integer(10);
Integer b2 = new Integer(10);
System.out.println(a1 == b1); // true
System.out.println(a2 == b2); // false
System.out.println(a1 == a); // true
System.out.println(a1.equals(a)); // true
System.out.println(a1 == a2); // false
System.out.println(a == a2); // true
}
解释:
1.System.out.println(a == b); // true
解释:
a
和b
都是基本类型int
,它们的值相同,所以比较结果为true
。
2.System.out.println(a1 == b1); // true
解释:
a1
和b1
都是通过直接赋值10
创建的Integer
对象。由于 Java 对于值在-128
到127
之间的整数进行缓存,a1
和b1
实际上指向同一个对象,所以结果为true
。
3.System.out.println(a2 == b2); // false
解释:
a2
和b2
是通过new Integer(10)
创建的,它们是两个不同的对象,虽然值相同,但内存地址不同,因此结果为false
。
4.System.out.println(a1 == a); // true
解释:这里发生了自动拆箱(unboxing),
a1
被转换成基本类型int
,然后与a
进行比较。由于它们的值相同,所以结果为true
。
5.System.out.println(a1.equals(a)); // true
解释:
equals()
方法比较的是值。a1
是Integer
对象,a
是int
基本类型,a1
自动拆箱为int
,然后与a
进行比较,值相同,因此结果为true
。
6.System.out.println(a1 == a2); // false
解释:
a1
是通过自动装箱(autoboxing)创建的,而a2
是通过new Integer(10)
创建的对象,两个对象的引用不同,结果为false
。
7.System.out.println(a == a2); // true
解释:
a2
是Integer
对象,通过自动拆箱,a2
被转换成基本类型int
,然后与a
进行比较,值相同,因此结果为true
。
7. 基本数据类型所对应的包装类
基本数据类型 | 包装类 |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |