Java中的“===”相当于什么?

29

在Java中比较两个值时,如何测试它们的类型和值是否相等?

我知道在JavaScript中可以使用===来实现这一点,所以我尝试在Java中使用了它,但是没有成功。

我知道这是一个简单的问题,但我已经尝试过搜索,却没有找到答案。


6
使用正确编写的equals方法进行比较a.equals(b) - luk2302
在JavaScript中,===不能用于测试类型和值是否相等。 var obj_a = {1: 2}; var obj_b = {1: 2}; console.log(obj_a === obj_b); // 结果为false - LiuXiMin
@LiuXiMin 我认为它只是不能与对象一起使用,但它可以与其他所有东西一起使用。 - JavaCakes
@JavaCakes No. === 在 JavaScript 中表示 严格相等。你无法用它来比较对象、数组和函数。在这里查看更多细节。 - LiuXiMin
除了那些以外的一切,那么。 - JavaCakes
2
以下的答案或多或少地给出了一个解释,但我想说不要拿苹果和橙子比较 :) 实际上,我能想到的在Java中最接近===的类比是.equals(),如果你正在比较String或数字(IntegerIntegerDoubleDouble),但对于原始类型和其他引用类型,它是==,但如果比较IntegerDouble(不同的装箱类型),则没有相应的等价物。总之,试着理解每个运算符在你使用的特定语言中是如何工作的。在两种不同的语言之间进行类比可能会更加混乱而不是有帮助。 - M A
9个回答

49

简述

在Java中,不存在这样的比较运算符:===,但可以使用==equals

更详细的解释

在JavaScript等弱类型语言中,您可以使用严格比较运算符(===),因为该语言允许比较具有不同类型的变量。

例如,在JavaScript中,如果您这样做,就不会得到编译错误:

var x = 10;
var y = 'foo';
console.log(x == y); // false

当你想要比较可能持有“相等”但类型不同的值的变量时,它是有用的。

例如

var x = 10;
var y = '10';
console.log(x == y)  // true
console.log(x === y) // false
在像Java这样的强类型语言中,您不需要使用严格比较运算符,因为该语言已经“处理”了类型比较。
例如:
int x = 10;
String y = "10";
System.out.println("10" == y); // true
System.out.println(x == y);    // compile error : Incompatible operand types int and String

总的来说,在Java中,使用===进行严格检查是没有必要的(会报告语法错误)。

首先,当您使用==运算符比较不同类型的值并且无法执行转换时,编译器会报错。

在上面Java代码的示例中,如果您想要比较xy,可以使用equals

int x = 10;
String y = "10";
System.out.println(y.equals(x)); // compile warning: Unlikely argument type for equals(): int seems to be unrelated to String

值得一提的是,请注意,equals 方法不能在基本类型上调用。

一些有用的阅读材料:


1
JavaScript没有double或integer类型,只有“数字”类型,它们本质上是doubles。因此,1010.0是相同的。 - Ivar
@lealceldeiro == 只检查引用。如果是相同的引用,则不能是另一种类型。 - Felix
1
@JavaCakes 他们为我写了同样的东西 (1, 2)。 - Ivar
2
@Nexevis 在Java 10中,var仅仅是一种纯语法糖,用于避免在可以从创建的实例中推断出变量声明类型时编写它。该语言仍然是强类型的。 - M A
1
简而言之:在Java中,===等同于.equals() - Cees Timmerman
显示剩余8条评论

6

我创建了一个函数,它在Java中复制了Javascript === 的功能

static boolean compareData(Object v1, Object v2)
{
    if(v1 != null && v2 != null)
        return (v1.getClass() == v2.getClass() && (v1.toString().equals(v2.toString())));
    else
    {
        return (v1 == null ? v2 == null : v1.equals(v2));
    }
}

我可以将任何数据类型(除了数组)的值传递给这个函数,并且只有当数据类型和值匹配时,它才返回 true,否则返回 false。类似 List 和 HashMap 这样的派生数据类型也可以使用。
该函数的调用方式如下:
float s1 = 0.f;
float s2 = 0.1f;

System.out.println(compareData(s1, s2)); //Returns false

float s1 = 0.0f;
float s2 = 0.0f;

System.out.println(compareData(s1, s2)); //Returns true

float s1 = 0.1f;
String s2 = "0.1f";

System.out.println(compareData(s1, s2)); //Returns false 

String s1 = "sdf";
String s2 = null;

System.out.println(compareData(s1, s2)); //Returns false 

String s1 = null;
String s2 = null;

System.out.println(compareData(s1, s2)); //Returns true

更新:我还成功地比较了数组,以下是代码片段,但我还没有对此代码进行全面测试,不过它已经适用于我进行的每个测试用例。

if(s1 != null && s2 != null)
    if(s1.getClass().isArray() && s2.getClass().isArray())
        compareDatab = s1.getClass().equals(s2.getClass()) && (Arrays.toString(s1).equals(Arrays.toString(s2)));
    else
        compareDatab = compareData(s1, s2);
else
    compareDatab = compareData(s1, s2);

使用上述代码片段(在上述代码片段之前应完成以下初始化,smh: P):

//s1 and s2 can be anything including Arrays and non-Array...
int[] s1 = {1,2,3};
int[] s2 = {1,2,3};
//compareDatab gives true

int[] s1 = {1,2,4};
int[] s2 = {1,2,3};
//compareDatab gives false

float[] s1 = {1,2,3};
int[] s2 = {1,2,3};
//compareDatab gives false

compareData()是此答案中之前提到的相同函数。

希望这对你有用。 :)


1
这似乎是一个有趣的小项目。+1 鼓励你去尝试。 - JG7
我的建议是在这种情况下使用Objects.equals、Objects.deepEquals、Objects.hash和Objects.compare。Objects类已经包含了你自己编写的许多功能。它还为你执行空值检查。另外一个好处是,它经过测试,不会出现插入错误的情况。 - Manuel

4

Java没有真值和假值的概念,因此也没有严格比较运算符。


1
所以 !(false == 0) 是真的。 - JavaCakes

4

=== 在弱类型语言中非常有用,比如Javascript,因为它可以验证被比较的对象是否为相同类型并避免隐式转换。

=== 在强类型语言中完全没有用处,例如Java,因为您不能比较不同类型的变量,除非编写一个专门的方法来执行此操作。


4
在Java中,您可以使用'=='比较基本类型(如int,double,char,long,float)。在这种情况下,比较的是值。
对于对象的比较,“==”不足够,因为仅当比较的对象的身份相同时,“==”才会评估为“true”-“identity”是存储对象的内存地址。这是由于所有类都隐式继承了“Object”类提供的所有方法,并且其中的“equals()”方法只包含基本实现。因此,任何涉及比较的对象所属的类,在数据结构中使用或在其自己的包之外使用时,都应包含一个稳定的equals()和hashCode()方法的实现,以提供正确的功能。
请查看以下实现:
public class MyClass {

  private final int val;
  private final String name;

  public MyClass(int val, String name) {
     this.val = val;
     this.name = name;
  }

  public int getVal() { return val; }

  public String getName() { return name; }

  public boolean equals(Object o) {
     if(o == null) return false;
     if(this == o) return true;
     if(!this.getClass().getSimpleName().equals(o.getClass().getSimpleName()) return false;

     MyClass other = (MyClass) o;

     return this.getVal() == other.getVal() && this.getName().equals(other.getName());
  }

  public int hashCode() { ... }

}

此外,请查看官方Java API以获取更多信息 https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html


3

我认为自己编写比较器并没有什么好处,特别是如果已经有原生实现的话。

java.util.Objects是你的朋友。

它包含了许多小助手,例如

Objects.compare(object1, object2, comparator);
Objects.equals(object1, object2);
Objects.deepEquals(object1, object2);
Objects.hash(object1, object2, object3, ...);

我在重写equals方法时使用了Objects.equals,在hashCode方法中使用了Objects.hash。它还会为您执行空值检查,最终代码看起来非常干净和易读。
例如:
...

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof Customer)) {
        return false;
    }
    Customer that = (Customer) o;
    return Objects.equals(firstName, that.firstName)
            && Objects.equals(lastName, that.lastName)
            && Objects.equals(street, that.street)
            && Objects.equals(houseNumber, that.houseNumber)
            && Objects.equals(postalCode, that.postalCode)
            && Objects.equals(city, that.city)
            && Objects.equals(emailAddress, that.emailAddress);
}

@Override
public int hashCode() {
    return Objects.hash(firstName,
            lastName,
            street,
            houseNumber,
            postalCode,
            city,
            emailAddress);
}

...

2
如果两个变量的类型不同,则无法进行比较,因此在这种情况下,使用==就足够了。如果它们不能转换,编译器将会抛出一个错误。"最初的回答"

2

在比较两个引用时,没有“===”运算符可供使用。您应该检查以下内容:

  • 它们是否指向同一个对象。

原始答案:最初的回答。

if(firstreference==secondreference) 
  1. 如果上述条件1不符合,则应通过instanceof运算符检查它们的类型:
"Original Answer"翻译成"最初的回答"。
if (secondreference instanctof classoffirstreference)

如果满足上述条件2,则应通过等于运算符检查属性比较,例如:```
  1. 如果满足上述条件2,则应通过等于运算符检查属性比较,例如:
firstreference.property1.equals(secondreference.property1)
//do this for all properties.

0
如果我们在 JS 中比较两个变量,我们可以使用 "==" 和 "==="。 "==" 比较值,而 "===" 比较类型。
var x = 10;
var y = '10';
console.log(x == y)  // true
console.log(x === y) // false

在Java中,这会导致编译错误,因为类型不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接