0
点赞
收藏
分享

微信扫一扫

【Java面向对象】包装类、基本使用、自动装箱、自动拆箱(Autoboxing and Unboxing)、包装类的判定(==、equals)、IntegerCache 缓存、valueOf 方法源码

f12b11374cba 2022-02-25 阅读 53

包装类

文章目录

包装类01–基本使用

对比引用类型,基本类型存在的一些缺陷:

  • 无法表示不存在的值(null 值)
  • 不能利用面向对象的方式去操作基本类型(比如直接用基本类型调用方法)
  • 当方法参数是引用类型时,基本类型无法传递

解决方案:可以自己将基本类型包装成引用类型

在这里插入图片描述

  • 其实Java中已经内置了基本类型的包装类(都在java.lang包中)

在这里插入图片描述

  • 数字类型的包装类(Byte\Short\Integer\Long\Float\Double)最终都继承自java.lang.Number

包装类02–细节

自动装箱、拆箱(Autoboxing and Unboxing)

  • 自动装箱:Java 编译器会自动基本类型转换为包装类(调用 valueOf 方法)
  • 自动拆箱:Java 编译器会自动包装类转换为基本类型(调用 xxxValue 方法)

自动装箱示例:Java 编译器会帮我们做很多工作,过一遍下面的示例即可。

Integer i1 = 10; // 自动装箱
// 等价于 Integer i1 = Integer.valueOf(10);

Object num = 10; // 自动装箱
// 等价于: Object num1 = Integer.valueOf(10);
public static void main(String[] args) {
	add(20); // 自动装箱
	// 等价于 add(Integer.valueOf(20)); 
}
static void add(Integer num) {}

自动拆箱示例:平时写代码这些都是不需要我们操心的,了解原理即可。

Integer i1 = 10;
int i2 = i1; // 自动拆箱
// 等价于: int i2 = i1.intValue();

System.out.println(i1 == 10); // 自动拆箱
// 等价于: System.out.println(i1.intValue() == 10);

Integer[] array = { 11, 22, 33, 44 }; // 包装类数组
	int result = 0;
	for (Integer i : array) {
	    // i.intValue() % 2 == 0
		if (i % 2 == 0) { // 自动拆箱
			// result += i.intValue();
			result += i; //自动拆箱
		}
	}

包装类的判等

  • 包装类的判等,不要使用 ==!= 运算符,应该使用 equals 方法
// 缓存范围: [-128, 127]
Integer i1 = 88;
Integer i2 = 88;
Integer i3 = 888;
Integer i4 = 888;

// 不推荐, 比较的是内存地址
System.out.println(i1 == i2); // true, 为什么呢? 缓存, 具体看下面
System.out.println(i3 == i4); // false

// 推荐, 先比内存地址, 再比值
System.out.println(i1.equals(i2)); // true
System.out.println(i3.equals(i4)); // true

你可能会好奇为什么 i1 == i2 会返回 true,是因为:

  • IntegerCache 类中缓存了 [-128, 127] 范围的 Integer 对象(因为很常用)
  • Integer.valueOf 方法会优先去 IntegerCache 缓存中获取 Integer 对象
// 缓存范围: [-128, 127]
Integer i1 = 88; // 从IntegerCache缓存中取值
Integer i2 = Integer.valueOf(88); // 从IntegerCache缓存中取值
Integer i3 = new Integer(88); // new 出来的对象必然是一个新的地址

System.out.println(i1 == i2); // true
System.out.println(i2 == i3); // false

查看 Java 源码可以知道 valueOf 方法与 new 对象不完全等价, valueOf先判断缓存中是否有该值,没有再去new

在这里插入图片描述

包装类使用注意

  • 基本类型数组】与【包装类数组】之间是不能自动装箱、拆箱
public static void main(String[] args) {
	// 基本类型数组不会自动装箱
	int[] nums1 = { 11, 22 };
	// test1(nums1); // error
	// Integer[] nums2 = nums1; // error
	
	// 包装类数组不会自动拆箱
	Integer[] nums3 = { 11, 22 };
	// test2(num3); // error
	// int[] nums4 = num3; //error
}

static void test1(Integer[] nums) {}
static void test2(int[] nums) {}
举报

相关推荐

0 条评论