自动装箱和拆箱、包装类空指针异常问题、包装类的缓存问题

2023-11-08

自动装箱和拆箱

自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转化。JDK1.5以后Java引入了自动装箱(autoboxing)和自动拆箱(unboxing)

自动装箱:

基本数据类型处于需要对象的环境中时,会自动转为”对象“。例如:‘
Integer i= 5;相当于编译器自动执行Integer i= Integer,valueOf(5)

自动拆箱子:

每当需要一个值时,对象会自动转成基本数据类型,没必要再去使用intvalue()

自动装箱过程时通过包装类的valueOf()方法,而自动拆箱过程是通过调用包装类的xxxValue()方法实现的(xxx代表的时对应的基本数据类型,如intVlaue(),doubleValue()等

自动装箱拆箱实际上是编译器来帮的忙,编译器在编译时依据你所写的语法,来决定是否进行装箱或者拆箱动作。


/*
 * 自动装箱/自动拆箱
 */
package com.wu.test;

public class AutoboxingUnboxing {
	public static void main(String[] args) {
		Integer i = 100;//自动装箱
//		相当于编译器自动为你做一下语法编译:
//		Integer i = Integer.valueOf(100);调用的是valueOf(100),而不是new Integer(100);
		
		int j = i;//自动拆箱
//		相当于编译器自动为你做一下语法编译:
//		int j = i.intValue();
 
	}

}

所以自动装箱和自动拆箱的功能是所谓的“编译器蜜糖(Complier Suger)”虽然使用这个功能很方便,但是在程序运行阶段得了解java的语义。

包装类空指针异常问题:

/*
 * 测试包装类空指针异常
 */
package com.wu.test;

public class Test01 {
	public static void main(String[] args) {
		Integer i = null;
		int j = i;
/*代码在编译时期是合法的,但是在运行时期会有错误
 * 因为其相当于下面两行代码
 * Integer i= null;
 * int j = i.intvalue();
 */
		
	}

}


Exception in thread "main" java.lang.NullPointerException
	at com.wu.test.Test01.main(Test01.java:10)

null表示i没有指向任何对象的实体,但作为对象的名称是合法的(不管这个对象名称是否指向某个对象的实体),由于实际上i 并没有指向任何对象的实体,所以也就不可能操作intValue()方法,这样上面的写法会出现NullPointerException的错误

自动装箱与拆箱:


/*
 * 自动装箱与拆箱
 * 结论:虽然很方便,但是不熟悉特性可能会出错。
 */
package com.wu.test;

public class Test02 {
	public static void main(String[] args) {
		Integer b = 23; //自动装箱
		int a = new Integer(20);//自动拆箱
//		下面的问题我们需要注意》
		Integer d =  null ;
		int c = d;//此处就是:d.intValue(),因此抛空指针异常。
		
	}

}

包装类的缓存问题

整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存 处理,其目的是提高效率。
缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间 的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。


/*
 * 包装类的缓存测试:
 */
package com.wu.test;

public class Test03 {
	public static void main(String[] args) {
		Integer in1 = -128;
		Integer in2 = -128;
		System.out.println(in1 == in2);//因为-128在缓存范围之内,当数字在[-128,127]之间时,返回的时数组中的某个元素
		System.out.println(in1.equals(in2));//true,因为equals方法是数值的比较
		Integer in3 = 1234;
		Integer in4 = 1234;
		System.out.println(in3 == in4);//因为1234不在缓存范围之内
		System.out.println(in3.equals(in4));//true
	}

}

在这里插入图片描述
注意:

1》JDK1,5以后,增加了自动装箱拆箱的功能,如:Integer i=100;int j = new Integer(100);
2》自动装箱调用的是valueOf()方法,而不是new Integer()方法。
3》自动拆箱调用的是xxxvalue()方法。
4》包装类为提高效率,对于-128~127范围类的值会进行缓存处理,超出范围后,对象之间不能再使用==进行数值比较,而是使用equals()方法。

/*
 * 定义一个简单的包装类:
 */
public class MyInteger {
	private int value;
	private static MyInteger[] cache = new MyInteger[256];
	
	public static final int Low = -128;
	public static final int High = 127;
	
	static {
		//[-128,127]
		for (int i=MyInteger.Low;i<=High;i++){
			//-128,0;-127,1;-126,2;
			cache[i+128] = new MyInteger(i);
		}
	}
	
	public static MyInteger valueOf(int i){
		if(i>=Low&&i<=High){
			return cache[i+128];
		}
		return new MyInteger(i);
	}

	@Override
	public String toString() {
		return this.value+ "";
	}
	public int intValue(){
		return value;
	}
	private MyInteger(int i){
		this.value = i;
	}
	public static void main(String[]args){
		MyInteger m = MyInteger.valueOf(30);
		System.out.println(m);
	}

}

1、

基本数据类型 包装类
int Integer
byte Byte
long Long
short Short
char Character
double Double
float Float
boolean Boolean

2、Number类和数字包装类是父子类关系,Number类是抽象类
3、包装类的两个基本作用:1.基本类型和包装类对象之间的互相转化2、包含每种基本数据类型的属性如:最大值,最小值等,以及相关操作等。
4、自动装箱拆箱指的是编译器在不同环境下根据书写语法对基本数据类型和包装类对象自动的调用Integer.valureOf()和xxxValue();方法转化
5、Integer类缓存的处理范围是【-128,127】。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动装箱和拆箱、包装类空指针异常问题、包装类的缓存问题 的相关文章

  • 使用 Hibernate 用瞬态对象更新持久对象

    每天 数据都是通过网络服务导入的 我创建一个新的 暂时的 实例我通过 JPA 注释在 hibernate 中映射的 pojo 的 我将数据从 Web 服务填充到瞬态实例中 我从数据库加载持久对象 我想用瞬态实例中的数据更新该持久对象 我以某
  • 合并 2 个 .jks 信任库文件

    我正在使用启用了 SSL 的 Tomcat 并使用信任库进行客户端身份验证 我有两个 jks trustore 文件 第一个 我将其用于 PROD 环境 另一个用于 TEST 环境客户端证书 我在 Tomcat 上部署了 Web 应用程序
  • 如何从球衣服务端点发送实体列表?

    我正在从球衣服务器发送实体列表 在客户端 我试图获取这些实体列表 但它给了元帅例外 为什么它在元素名末尾添加 s 即 emps 而不是 emp XmlRootElement public class Emp Server side code
  • 图像在 3D 空间中绕 Y 轴旋转

    我有一个 BufferedImage 我想用 theta 角而不是仿射变换绕 Java 中的 Y 轴旋转图像 图片 旋转将如下图所示 矩形将是图像 我可以通过旋转图像的每个像素并绘制图像来做到这一点 因为我必须旋转很多图像 所以我认为这不是
  • 如何在 Android 中签署 AAR Artifacts?

    我目前正在开发一个 AAR android 库 我想用我自己的密钥对已发布的工件进行签名 以便我可以确定我是否发布了具有相同名称和功能的假 aar 注意事项1 我希望能够以编程方式检查我的库的真实性 即使是一个伪造的库 只是伪造了我的 aa
  • Byte[] 和 java.lang.OutOfMemoryError 按位读/写文件

    我正在努力擦除 Android 中的一些可用空间 这是我的代码 private void creatingFileDelete int size int passMode File lastFile new File Environment
  • 简单的Java程序插入USB热点后速度慢100倍

    我有以下Java程序 class Main public static void main String args throws java io IOException long start System nanoTime java io
  • 如何使用Gson将JSONArray转换为List?

    在我的 Android 项目中 我试图将收到的 JSONArray 转换为列表 在 的帮助下这个答案 https stackoverflow com questions 8371274 how to parse json array in
  • 如何防止我的 servlet 被其他网站调用

    好的 我有一个像这样的简单的 servlet public class SimpleServlet extends HttpServlet public void doPost HttpServletRequest req HttpServ
  • Android 的@hide 注解到底有什么作用?

    Android中很多内部API都被标记出来了 hide What exactly这是吗 另一个答案 https stackoverflow com questions 17035271 what does hide mean in the
  • 覆盖乔达一周的第一天?

    是否有可能覆盖乔达弱的第一天sunday 因为 Joda 使用Monday作为一周的第一天 如果有办法的话 谁能解释一下 我在 SOF 中提到了以下主题 乔达时间 一周的第一天 https stackoverflow com questio
  • 基于磁盘的 HashMap [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Java 是否有 或者是否有可用的库 允许我拥有基于磁盘的 HashMap 它不需要是原子的或任何东西
  • 错误包括 bouncycastle 提供商

    我需要使用bouncycastle provider我的项目中的库 我已将其包含在 gradle 项目中 apply plugin application sourceCompatibility 1 6 version 1 0 0 main
  • org.apache.poi 中的异常

    我试图编写一个可以读取和写入的程序 xlsx文件中 下面提供的代码旨在能够编写其第一个 Excel 程序 package excel reader import java io FileOutputStream import java io
  • Java中如何将Object[]转换为String[]?

    我有一个关于 Java 的问题 我有一个Object Java默认的 不是用户定义的 我想将它转换为String 谁能帮我 谢谢 这是转换 for int i 0 i lt objectArr length i try strArr i o
  • 致命异常:OkHttp 调度程序

    我在 Android 应用程序中使用 OkHttp 库向天气 API 发出 Web 请求 我已经实现了我的代码 但在执行请求时遇到了致命异常 我也已经在我的清单中添加了互联网权限 MainActivity java private Curr
  • 找出对象列表中是否包含具有指定字段值的内容?

    我有一个从数据库收到的 DTO 列表 它们有一个 ID 我想确保我的列表包含具有指定 ID 的对象 显然 在这种情况下创建具有预期字段的对象不会有帮助 因为 contains 调用 Object equals 并且它们不会相等 我想出了这样
  • 优雅地避免 Java 中的 NullPointerException

    考虑这一行 if object getAttribute someAttr equals true 显然这一行是一个潜在的错误 属性可能是null我们会得到一个NullPointerException 因此我们需要将其重构为以下两个选择之一
  • 如何将字符串解析为map

    有一个像A B C D E F这样的字符串 如何将其解析为map 我会使用拆分 String text A B C D E F Map
  • 如何将元素添加到通用集合

    我想知道如何将专用对象添加到通用集合中 我正在使用以下代码 Collection

随机推荐