Java基本类型和包装类什么情况下判断相等(“==“或“equals“)?

简介: Java基本类型和包装类什么情况下判断相等(“==“或“equals“)?

[1] 先讨论一个面试题


int a = 1;
Integer b = 1;
Integer c = new Integer(1);
Integer d = Integer.valueOf(1);
int e = d;
int f = d.intValue();

  请问以下式子的值?为什么?

a == b // true
a == c // true
b == c // false

[2] "=="与"equals"用法的不同


  对于Java中的判断相等,有两种方法:

  · 操作符==

  · 方法equals

  对于==操作符来说,区分是基本类型还是引用类型

  1、如果比较的数据是基本类型,则比较它们的值;

  2、如果比较的是对象,则会比较对象的内存地址。

  3、另外,如果一个是基本类型、一个是包装类型,在比较前会先把包装类型拆箱成基本类型,然后进行比较。

  equals方法是用来判断其他的对象是否和该对象相等,equals()方法在Object类中定义如下:

public boolean equals(Object obj) {  
    return (this == obj);  
}  

 很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们知道,String 、Math、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。


 所以对于equals来说,区分调用者是否重写了equals方法:


 1、类没有重写equals()方法:通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是Object类equals()方法,比较它们的地址值。

 2、类重写了equals()方法:一般我们都重写equals()方法来比较两个对象中的属性是

否相等;若它们的属性相等,则返回true(即认为这两个对象相等)。

【注意】equals()不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。

[3] 基本类型和包装类型的区别


  1、对于基本类与包装类的转换,Java提供了装箱、拆箱机制;

  2、包装类的缓存机制。Byte , Short , Integer , Long这 4 种包装类默认创建了数值 [-128,127]的相应类型的缓存数据, Character创建了数值在[0,127]范围的缓存数据,Boolean直接返回 True or False

  3、Java语言是面向对象的,但是Java的基本数据类型不是,将基本数据类型设计成类,可以增强Java面向对象的性质;

  4、包装类可以用于泛型,而基本类型不可以;

  5、基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。包装类型需要占用更多的内存空间。假如没有基本类型的话,对于数值这类经常使用到的数据来说,每次都要通过new一个包装类型就显得非常笨重。

[4] 3种创建基本类型的方式


  以int为例,这里我们把参与比较的类型分为三种:int直接new出来的Integer对象自动装箱出来的Integer对象。分类细节如图:

image.png

[4.1] int


int a = 1;
Integer b = 1;
int e = b;
int f = b.intValue();

  如上代码中,变量a、e、f的创建:

  a属于直接创建;

  e是对Integer类型进行自动拆箱,转化成int类型;

  f是调用变量bintValue()方法,可以理解为显式的拆箱。

[4.2] 直接new出来的Integer对象


Integer c = new Integer(1);

  没啥好说的。包装类型存储的是堆中的引用。

[4.3] 自动装箱出来的Integer对象


Integer b = 1;
Integer c = 128;
Integer d = Integer.valueOf(1);

  如上代码中,变量b、c的创建使用了自动装箱机制,自动装箱机制会调用指定包装类的valueOf方法,像变量d那样。

  由于具有包装类自动装箱时具有缓存机制,而它就是通过valueOf方法实现的,其代码如下:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

  可以看到,在范围[-128,127]之间,包装类Integer自动装箱定义时会返回缓存中数据。

[5] 综上,我们回到面试题


int a = 1; // 直接定义,存在栈中
Integer b = 1; // 自动装箱,且1在[-128,127],b是缓存中数据
Integer c = new Integer(1); // new对象,存在堆中的引用

  由于对于操作符==,如果一个是基本类型、一个是包装类型,在比较前会先把包装类型拆箱成基本类型,然后进行比较。所以a == ba == c都为true。

  对于同样是包装类型的变量b、c,操作符==比较的是它们的引用,而一个是缓存中数据,一个在堆中,所以b == c为false。

a == b // true
a == c // true
b == c // false

【注意】对于变量b、c的比较,它们是引用类型了,我们应该使用equals()来判断它们的值是否相等,IDEA会有提示。而变量a、b,变量a、c之间的比较,不能用equals(),因为基本类型不可以使用equals()。

相关文章
|
15天前
|
JavaScript Java 编译器
Java包装类和泛型的知识点详解
Java包装类和泛型的知识点的深度理解
|
1月前
|
存储 Java 数据库
java包装类的作用、基本类型和包装类型的区别
java包装类的作用、基本类型和包装类型的区别
31 0
java包装类的作用、基本类型和包装类型的区别
|
1月前
|
Java
java equals和==
==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法 public boolean equals(0bjectobj):参数可以是任何对象,只有参数是一个字符串并且内 容相同的才会给true;否则返回false 注意事项: 1.任何对象都能用object进行接收。 2.equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。 3.如果比较双方一个常量一个变量,推荐把常量字符串写在前面。 推荐:"abc".equals(str) 不推荐:str.equals("abc") public boolean egualsIgnoreCas
10 1
|
1月前
|
存储 缓存 Java
JAVA基本数据类型的包装类
JAVA基本数据类型的包装类
15 0
|
1月前
|
安全 Java
Java中的基本类型原子类介绍
Java中的基本类型原子类介绍
13 1
|
1月前
|
存储 Java API
Java 包装类:原始数据类型与迭代器
Iterator 接口提供了一种迭代集合的方法,即顺序访问集合中的每个元素。它支持 hasNext() 和 next() 方法,用于检查是否存在下一个元素以及获取下一个元素。 获取 Iterator 可以使用集合的 iterator() 方法获取 Iterator 实例:
52 0
|
1月前
|
存储 Java
Java面向对象之——包装类
Java面向对象之——包装类
|
1月前
|
Java
Java中常见需要重写equals方法的类
Java中常见需要重写equals方法的类
|
1月前
|
Java
Java 中表示整数的包装类Integer(详解)
Java 中表示整数的包装类Integer(详解)
|
3月前
|
Java
Java中 ==与equals的区别
Java中 ==与equals的区别
17 1