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

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(使用前将#替换为@)

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

  • Java中ArrayList的交集和并集

    有什么方法可以做到这一点吗 我正在寻找 但没有找到 另一个问题 我需要这些方法 以便我可以过滤文件 有些是AND过滤器 有些是OR过滤器 就像集合论中的那样 所以我需要根据所有文件和保存这些文件的联合 相交 ArrayList 进行过滤 我
  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • Spring应用中Eureka健康检查的问题

    我正在开发一个基于 Spring 的应用程序 其中包含多个微服务 我的一个微服务充当尤里卡服务器 到目前为止一切正常 在我所有其他微服务中 用 EnableEurekaClient 我想启用这样的健康检查 应用程序 yml eureka c
  • Junit:如何测试从属性文件读取属性的方法

    嗨 我有课ReadProperty其中有一个方法ReadPropertyFile返回类型的Myclass从属性文件读取参数值并返回Myclass目的 我需要帮助来测试ReadPropertyFile方法与JUnit 如果可能的话使用模拟文件
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 如何使用assertEquals 和 Epsilon 在 JUnit 中断言两个双精度数?

    不推荐使用双打的assertEquals 我发现应该使用带有Epsilon的形式 这是因为双打不可能100 严格 但无论如何我需要比较两个双打 预期结果和实际结果 但我不知道该怎么做 目前我的测试如下 Test public void te
  • 如何更改javaFX中按钮的图像?

    我正在使用javaFX 我制作了一个按钮并为此设置了图像 代码是 Image playI new Image file c Users Farhad Desktop icons play2 jpg ImageView iv1 new Ima
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]-MySQL

    我是 Hibernate 的新手 我目前正在使用 Spring boot 框架并尝试通过 hibernate 创建数据库表 我知道以前也问过同样的问题 但我似乎无法根据我的环境找出如何修复错误 休眠配置文件
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem

随机推荐