具有相同地址的两个对象不相等(==)

Two objects with same address not equal (==)

我有一个 属性 和一个 Team 类型的方法: this.teamflag.getTeam()(这只是 属性 的单行 getter)。

以下是相应的 toString() 输出: org.bukkit.craftbukkit.v1_12_R1.scoreboard.CraftTeam@674e0730org.bukkit.craftbukkit.v1_12_R1.scoreboard.CraftTeam@674e0730

team == flag.getTeam() returns false, 而
team.hashCode() == flag.getTeam().hashCode() returns true
team.toString().equals(flag.getTeam().toString()) returns true

public class PlayerTimer extends BukkitRunnable {

    Domination plugin;
    Player player;
    Team team;
    public PlayerTimer(Domination plugin, Player player) {
        this.plugin = plugin;
        this.player = player;
        for (Team team : plugin.getWorldGameScoreboards().get(plugin.getCurrentWorld()).getTeams()) {
            for (OfflinePlayer offlinePlayer : team.getPlayers()) {
                if (offlinePlayer.getPlayer() == player) {
                    this.team = team;
                    break;
                }
            }
            if (this.team != null) break;
        }
    }

    @Override
    public void run() {
        for (Flag flag : plugin.getWorldFlags().get(plugin.getCurrentWorld())) {
            for (OfflinePlayer offlinePlayer : team.getPlayers()) {
                if (offlinePlayer.isOnline()) {
                    Player player = offlinePlayer.getPlayer();
                    double scaledDistance = player.getLocation().distance(flag.getLocation()) / 5;  // max 5 blocks away
                    if (scaledDistance < 1) {
                        plugin.log(team + " : " + flag.getTeam() + ", " + (team == flag.getTeam()) + "; " + team.equals(flag.getTeam()) + (team.hashCode() == flag.getTeam().hashCode()) + "^ " + team.toString().equals(flag.getTeam().toString());
                        ...
                    }
                }
            }
        }
    }
}

为什么 == 没有返回 true

答案是您正在尝试比较对象。两个对象可以有相同的值,但它们在内存中的位置不同。当您使用 == 时,您比较的是指针(它们在内存中具有不同的地址)而不是对象值。为此,您应该像在第三行中那样使用 .equals() 。 如果对象是在相同的 "way" 中创建的,那么 hashCode 将是相同的(使用相同的 class 和字段,因此 hashCode 方程给出相同的值 - 这是正确的)。总而言之,当你在两个具有相同属性值的对象上使用 == 时,它们实际上是两个具有不同内存地址的不同对象。

我认为误解来自 toString() 方法的实现方式。在一个对象上调用 toString 将产生一个字符串 equivalent to the following value

getClass().getName() + '@' + Integer.toHexString(hashCode())

要实现的关键点是 Object 的哈希码是 based on memory location, hashcode for a String is based on the String's value。因此可以产生相同的 toString() 输出,不同的 String 对象具有相同的内容。