Java基础 --- 包装类和自动拆装箱 Wrapper Class and Autoboxing

什么是包装类

在这里插入图片描述

为什么需要包装类and为什么需要基本数据类型

  • Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,将每个基本数据类型设计一个对应的类进行代表,这种方式增强了Java面向对象的性质。把基本数据类型包装成引用类型可以解决很多问题。比如:
  • 在集合类中,我们是无法将int 、double等类型放进去的,因为集合的容器要求元素是Object类型。
  • 当我们想知道int取值范围的最小值,我们需要通过运算,如下面所示,但是有了包装类,我们可以直接使用Integer.MAX_VALUE即可
  • 为什么需要基本数据类型
  • 引用类型存储在heap上,读写速度较慢。而基本数据类型存储在stack上,读写速度的比较快

包装类和基本数据类型的转换

由primitive -> wrapper

  • 以下写法已经被淘汰 --> 替换成第二张图,原因是因为value of有缓存
    在这里插入图片描述
    在这里插入图片描述
  • 或者使用自动封箱(auto-boxing),Java自动调用ValueOf函数
    在这里插入图片描述

由wrapper --> primitive

  • 使用value函数
    在这里插入图片描述
  • 或使用自动拆箱(auto-unboxing)
    在这里插入图片描述

Wrapper Class的缓存

  • Java在第一次使用valueOf函数时,会通过静态代码块(static code block)创建一个常用值数组(ex: integer为-128到127),这样可以避免重复创建新的对象。
  • 源代码分析(Integer类)
    在这里插入图片描述
  • 可以发现,只要Integer类第一次被使用到(因为创建Integer对象一定会用到valueOf函数,valueOf函数里用到了cache类,所以cache内部类会被加载),Integer的静态内部类就被加载,加载的时候会创建-128到127的Integer对象,同时创建一个数组cache来缓存这些对象。当使用valueOf()方法创建对象时,就直接返回已经缓存的对象,也就是说不会再新建对象;当使用new关键字or使用valueOf()方法创建小于-128大于127的值对象时,就会创建新对象。

各包装类的缓存范围
在这里插入图片描述

关于缓存:

public class ValuePassing {
	
	public static void fun1(Integer i, Integer j) {
		System.out.println("在fun1中赋值前i的地址是: " + System.identityHashCode(i));
		System.out.println("在fun1中赋值后j的地址是: " + System.identityHashCode(j));
		//对i和j同时赋予一样的值后(在-128-127之间),地址一样
		i = 10; 
		j = 10;
		System.out.println("-----------------------------------------------");
		System.out.println("在fun1中赋值后i的地址是: " + System.identityHashCode(i));
		System.out.println("在fun1中赋值后j的地址是: " + System.identityHashCode(j));
	}
	
	public static void main(String[] args) {
        Integer i = 5;
        Integer j = 20;
        System.out.println("在main中i的地址是: " + System.identityHashCode(i));
        System.out.println("在main中j的地址是: " + System.identityHashCode(j));
        System.out.println("-----------------------------------------------");
        fun1(i, j);
    }
}

output:
在main中i的地址是: 1072591677
在main中j的地址是: 1523554304
-----------------------------------------------
在fun1中赋值前i的地址是: 1072591677
在fun1中赋值后j的地址是: 1523554304
-----------------------------------------------
在fun1中赋值后i的地址是: 1175962212
在fun1中赋值后j的地址是: 1175962212
public class ValuePassing {
	
	public static void fun1(Integer i, Integer j) {
		System.out.println("在fun1中赋值前i的地址是: " + System.identityHashCode(i));
		System.out.println("在fun1中赋值后j的地址是: " + System.identityHashCode(j));
		
		//不在-128-127之间地址则不一样
		i = 1000; 
		j = 1000;
		System.out.println("-----------------------------------------------");
		System.out.println("在fun1中赋值后i的地址是: " + System.identityHashCode(i));
		System.out.println("在fun1中赋值后j的地址是: " + System.identityHashCode(j));
	}
	
	public static void main(String[] args) {
        Integer i = 5;
        Integer j = 20;
        System.out.println("在main中i的地址是: " + System.identityHashCode(i));
        System.out.println("在main中j的地址是: " + System.identityHashCode(j));
        System.out.println("-----------------------------------------------");
        fun1(i, j);
    }
}

output:
在main中i的地址是: 1072591677
在main中j的地址是: 1523554304
-----------------------------------------------
在fun1中赋值前i的地址是: 1072591677
在fun1中赋值后j的地址是: 1523554304
-----------------------------------------------
在fun1中赋值后i的地址是: 1175962212
在fun1中赋值后j的地址是: 918221580
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值