基本数据类型和包装类的关系(以int和Integer为例)

本文详细解析了Java中自动装箱、拆箱的过程及其内部机制,并通过实例展示了基本类型与引用类型间的转换规则,同时深入探讨了Integer类的equals方法与valueOf方法的工作原理。
public void test(){
		int a=10;	
		Integer b=new Integer(10);
		Integer d= Integer.valueOf(10);
		Integer e= Integer.valueOf(10);
		Integer c=10;
		Integer f=10;
		System.out.println(a==b);//b自动拆箱int。基本类型比较值 true
		System.out.println(a==c);//将右边的1自动装箱,然后将c自动拆箱比较值true
		System.out.println(c==b);//b,c都是引用类型,比较地址。指向不同对象 false
		System.out.println(c.equals(b));//都是引用数据类型,重写equals。比较的是值true	
		System.out.println(c.equals(a));//首先将a自动装箱。相同的对象相同的值。true 
		System.out.println(c.equals(new Float(10)));//对象不同值相同。false
		System.out.println(c.equals(new Integer(1)));//对象相同但是值不同false
		System.out.println(a==d);//含有基本数据类型时,将包装类自动拆箱比较值true
		System.out.println(d.equals(e));//同类型同值true
		System.out.println(d==e);//比较地址。-128<value<127是创建了相同对象。true
		System.out.println(d==f);//true
	}

主要涉及的就是自动装,拆箱。以及Integer重写的equals方法和自己带的valueof方法。

==:对于基本的数据类型(8种,String不是),比较的是值

        对于引用数据类型(除基本类型以外),比较的是地址。也即两个引用是否指向同一个对象。

equals:对于重写了object下的equals方法来说,大部分比较的是值(若是自己定义的类没有重写,则比较的仍是地址)。注意比较得是值的有一个前提就是两个比较的是同一类型。这可以在重写的equals源码中看见(Integer)

 

源码:  public boolean equals(Object obj) {

 

if (obj instanceof Integer) {
    return value == ((Integer)obj).intValue();
}
return false;

 

    }

valueof:对于该方法需要注意的是它在[-128,127]内创建是同一个对象,这是JVM为了便于提高效率决定的。在源码中可以看见(Integer为例)

 

源码:

 public static Integer valueOf(int i) {

 

final int offset = 128;
if (i >= -128 && i <= 127) { // must cache 
    return IntegerCache.cache[i + offset];
}
        return new Integer(i);

 

    }。

 

<think>嗯,用户问的是Java中Integer包装int基本数据类型区别及使用场景。首先,我需要回忆一下这两者的基本概念。int基本数据类型,而Integer是它的包装。根据引用[1][2],包装主要是为了将基本型转为对象,这样可以在面向对象的场景中使用,比如集合。 接下来,我得想它们的区别有哪些。型不同,一个是基本型,一个是。然后默认值不同,int默认是0,而Integer是null,这在POJO中很重要,引用[3]提到POJO属性必须用包装,因为null可以表示缺失,而0可能有业务含义。存储位置也不同,int在栈,Integer对象在堆,这可能影响性能,特别是在大量使用时。自动拆箱可能带来性能开销,这也是需要注意的地方。 然后是使用场景。比如集合必须用包装,因为泛型不支持基本型。引用[2]提到集合元素必须是Object型。另外,数据库映射时,如果字段可能为null,用包装更合适,避免默认值的问题。方法参数返回值如果需要表示缺失值,包装更好。而局部变量或者频繁计算的地方用int更高效,引用[3]里推荐局部变量用基本型。 还需要注意==equals区别,引用[4]的子说明Integer在缓存范围内的比较结果不同,这里要提醒用户使用equals来比较对象的值。另外,自动箱的陷阱,比如循环中频繁拆箱可能导致性能问题,这也是实际开发中常见的坑。 用户可能的深层需求是理解何时使用哪一种,避免常见的错误,比如空指针或者性能问题。他们可能在开发中遇到了选择困难,或者看到别人的代码混用两种型,需要明确指导。需要结合引用中的POJO、RPC、泛型等场景来举说明,让用户有更直观的理解。 最后,生成相关问题的时候,要覆盖缓存机制、自动拆箱箱、性能对比等,这些都是常见面试题,能帮助用户深入理解。</think>### Java Integer包装int基本数据类型区别及使用场景 #### 一、核心区别 1. **型本质** - `int`是基本数据类型,直接存储数值,占用固定内存(4字节) - `Integer`是包装(`java.lang.Integer`),属于对象型,封了`int`值相关操作方法 2. **默认值差异** - `int`默认值为`0` - `Integer`默认值为`null`(未初始化时可能引发空指针异常) *POJO属性必须使用包装以区分"未赋值""0值"[^3]* 3. **存储方式** - `int`直接存储在栈内存 - `Integer`对象存储在堆内存,通过引用访问 ```java int a = 100; // 直接数值存储 Integer b = new Integer(100); // 对象引用存储 ``` 4. **自动箱/拆箱** Java编译器支持的自动转换机制: ```java Integer c = 200; // 自动箱:Integer.valueOf(200) int d = c; // 自动拆箱:c.intValue() ``` #### 二、关键特性对比 | 特性 | int | Integer | |---------------------|--------------|------------------| | 泛型支持 | ❌ 不可直接使用 | ✅ 可用作型参数 | | 集合存储 | ❌ | ✅ | | 算术运算效率 | ⭐⭐⭐⭐ | ⭐⭐ | | null处理能力 | ❌ | ✅ | | 方法参数传递 | 值传递 | 引用传递 | | 缓存机制(-128~127)| ❌ | ✅ | #### 三、使用场景指南 ✅ **优先使用int的场景** - 局部变量声明 - 高频数学运算 - 数组存储(`int[]`性能优于`Integer[]`) - 循环控制变量 ✅ **必须使用Integer的场景** 1. 集合元素存储 ```java List<Integer> list = new ArrayList<>(); // 集合只能存储对象[^2] ``` 2. 数据库实体字段(允许null值表示数据缺失) 3. RPC方法参数/返回值(需支持null语义)[^3] 4. 泛型型参数 ```java Map<String, Integer> map = new HashMap<>(); ``` 5. 需要对象特性时(如调用`compareTo()`方法) #### 四、典型问题与陷阱 1. **==equals区别** ```java Integer a = 127; Integer b = 127; System.out.println(a == b); // true(缓存范围内)[^4] Integer c = 300; Integer d = 300; System.out.println(c == d); // false(超出缓存范围) ``` *建议始终使用equals()进行值比较* 2. **自动箱的性能损耗** 循环中的频繁箱操作会导致性能下降: ```java Long sum = 0L; // 错误示范:每次循环都会箱 for(long i=0; i<1000000; i++){ sum += i; // 等价于sum = Long.valueOf(sum.longValue() + i) } ``` 3. **空指针风险** ```java Integer count = null; int result = count; // 运行时抛出NullPointerException ``` #### 五、最佳实践建议 1. **型选择原则** - 确定需要对象特性时用包装 - 确定数值范围且需高性能计算时用基本型 - POJO属性统一使用包装[^3] 2. **数值比较规范** ```java Integer x = 500; Integer y = 500; // 正确方式 if(x.equals(y)) {...} // 值比较 if(x.intValue() == y) {...} // 拆箱比较 ``` 3. **缓存优化技巧** 对常用数值优先使用自动箱(-128~127已缓存): ```java Integer a = 100; // 使用缓存对象 Integer b = new Integer(100); // 创建新对象(不推荐) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值