Java 和等于() 方法中的泛型类:类型安全

我想重写泛型类中的 equals() 方法,为此,我必须将 Object 转换为我的泛型类型 Pair。


我添加了@SuppressWarnings(“未选中”)来“静音”警告,但问题仍然存在。方法也不适用于泛型类型,因此使用 T.getType() 是不可能的。


public class Pair<T, U> {

    private T first;

    private U second;


    public Pair(T _first, U _second)

    {

        first = _first;

        second = _second;

    }


    public boolean equals(Object obj) {

         if (this == obj)

           return true;

         if (obj == null)

           return false;

         if (getClass() != obj.getClass())

           return false;


        //Problem ahead!!!

         Pair<T, U> other = (Pair<T, U>) obj;


                   ...

    }

}

是否有任何普遍的良好做法或“技巧”可以正确,安全地做到这一点?


qq_花开花谢_0
浏览 83回答 5
5回答

慕容森

您可以投射到 a 并调用 和 :objPair<?, ?>equalsfirstsecondPair<?, ?> other = (Pair<?, ?>) obj;return other.first.equals(first) && other.first.equals(second);这样,类型检查将由 和 处理,无论和是什么。T.equalsU.equalsTU

交互式爱情

你可以这样写你的方法:equals@Overridepublic boolean equals(Object object) {&nbsp; &nbsp; boolean equal = false;&nbsp; &nbsp; if(this == object){&nbsp; &nbsp; &nbsp; &nbsp; equal = true;&nbsp; &nbsp; } else if(object instanceof Pair<?, ?>) {&nbsp; &nbsp; &nbsp; &nbsp; // Check that object is an instance of Pair<?, ?>, this will also null check.&nbsp; &nbsp; &nbsp; &nbsp; // Then just case object to Pair<?, ?> like.&nbsp; &nbsp; &nbsp; &nbsp; Pair<?, ?> pair = (Pair<?, ?>) object;&nbsp; &nbsp; &nbsp; &nbsp; if(((this.first == null && pair.first == null) || (this.first != null && this.first.equals(pair.first))) &&&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((this.second == null && pair.second == null) || (this.second != null && this.second.equals(pair.second)))){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; equal = true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return equal;介于 之间有点像通配符,它实际上被归类为无界通配符;这意味着尚未指定类的类型。?<>将检查两件事,首先它将检查对象是否不为空,因此为您创建安全性,然后它将检查该对象是否为类型。object instanceof Pair<?, ?>nullPair<?, ?>您可以在此处阅读有关通配符的信息根据,如果您要覆盖,也不要忘记覆盖。ntalbsequalshashCode@Overridepublic int hashCode() {&nbsp; &nbsp; final int prime = 31;&nbsp; &nbsp; int result = super.hashcode;&nbsp; &nbsp; result = result * prime + (this.first == null ? 0 : this.first.hashCode());&nbsp; &nbsp; result = result * prime + (this.second == null ? 0 : this.second.hashCode());&nbsp; &nbsp; return result;}为什么当我覆盖等于时,我必须覆盖哈希码?您必须覆盖每个类中覆盖等于 () 的哈希码 ()。如果不这样做,将导致违反 Object.hashCode() 的总协定,这将阻止您的类与所有基于哈希的集合(包括哈希映射、哈希集和哈希表)一起正常运行。

喵喔喔

您可以使用 来检查对象的类型,然后安全地投射它。instanceofif(obj&nbsp;instanceof&nbsp;Pair){ &nbsp;&nbsp;&nbsp;Pair&nbsp;other&nbsp;=&nbsp;(Pair)&nbsp;obj; }

慕的地6264312

由于泛型类型在编译时被擦除,因此无法在运行时中检查该类型。所以你应该把它扔到.Pair<?,?>如果使用 JDK 7 或更高版本,则还可以在方法中使用。这将简化代码,因为您不必担心是否为 。Objects.equals(..)equalsfirstsecondnullPair<?, ?> pair = (Pair<?, ?>) obj;return Objects.equals(first, pair.first) &&&nbsp; Objects.equals(second, pair.second);另外,如果在类中添加了方法,请不要忘记实现。hashCodeequals@Overridepublic int hashCode() {&nbsp; return Objects.hash(first, second);}

互换的青春

首先请记住,泛型仅在编译时处于活动状态。它们是编译时检查的额外层,以确保您不会滥用可以采用不同类型的容器或函数。还要记住,自Java第一个版本以来,它一直存在,而泛型是在Java 1.5中引入的。因此,对于这种特定方法,您将有一些类型转换要做,这是很自然的。equals()转换对象后,您无论如何都会检查 的每个元素,因此,如果它们属于不同的类型,它们也将无法进行相等性检查。Pair
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java