为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

qq_花开花谢_0 2022-09-22 15:54:47

我想重写泛型类中的 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;


                   ...

    }

}

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


查看完整描述

5 回答

?
慕容森

TA贡献1486条经验 获得超17个赞

您可以投射到 a 并调用 和 :objPair<?, ?>equalsfirstsecond


Pair<?, ?> other = (Pair<?, ?>) obj;

return other.first.equals(first) && other.first.equals(second);

这样,类型检查将由 和 处理,无论和是什么。T.equalsU.equalsTU


查看完整回答
反对 回复 2022-09-22
?
交互式爱情

TA贡献1383条经验 获得超3个赞

你可以这样写你的方法:equals


@Override

public boolean equals(Object object) {

    boolean equal = false;


    if(this == object){

        equal = true;

    } else if(object instanceof Pair<?, ?>) {

        // Check that object is an instance of Pair<?, ?>, this will also null check.

        // Then just case object to Pair<?, ?> like.

        Pair<?, ?> pair = (Pair<?, ?>) object;


        if(((this.first == null && pair.first == null) || (this.first != null && this.first.equals(pair.first))) &&

                ((this.second == null && pair.second == null) || (this.second != null && this.second.equals(pair.second)))){

            equal = true;

        }

    }

    return equal;

介于 之间有点像通配符,它实际上被归类为无界通配符;这意味着尚未指定类的类型。?<>


将检查两件事,首先它将检查对象是否不为空,因此为您创建安全性,然后它将检查该对象是否为类型。object instanceof Pair<?, ?>nullPair<?, ?>


您可以在此处阅读有关通配符的信息


根据,如果您要覆盖,也不要忘记覆盖。ntalbsequalshashCode


@Override

public int hashCode() {

    final int prime = 31;

    int result = super.hashcode;


    result = result * prime + (this.first == null ? 0 : this.first.hashCode());

    result = result * prime + (this.second == null ? 0 : this.second.hashCode());


    return result;

}

为什么当我覆盖等于时,我必须覆盖哈希码?


您必须覆盖每个类中覆盖等于 () 的哈希码 ()。如果不这样做,将导致违反 Object.hashCode() 的总协定,这将阻止您的类与所有基于哈希的集合(包括哈希映射、哈希集和哈希表)一起正常运行。


查看完整回答
反对 回复 2022-09-22
?
喵喔喔

TA贡献1410条经验 获得超1个赞

您可以使用 来检查对象的类型,然后安全地投射它。instanceof

if(obj instanceof Pair){
   Pair other = (Pair) obj;
}


查看完整回答
反对 回复 2022-09-22
?
慕的地6264312

TA贡献1516条经验 获得超6个赞

由于泛型类型在编译时被擦除,因此无法在运行时中检查该类型。所以你应该把它扔到.Pair<?,?>


如果使用 JDK 7 或更高版本,则还可以在方法中使用。这将简化代码,因为您不必担心是否为 。Objects.equals(..)equalsfirstsecondnull


Pair<?, ?> pair = (Pair<?, ?>) obj;

return Objects.equals(first, pair.first) &&

  Objects.equals(second, pair.second);

另外,如果在类中添加了方法,请不要忘记实现。hashCodeequals


@Override

public int hashCode() {

  return Objects.hash(first, second);

}


查看完整回答
反对 回复 2022-09-22
?
互换的青春

TA贡献1464条经验 获得超6个赞

首先请记住,泛型仅在编译时处于活动状态。它们是编译时检查的额外层,以确保您不会滥用可以采用不同类型的容器或函数。

还要记住,自Java第一个版本以来,它一直存在,而泛型是在Java 1.5中引入的。因此,对于这种特定方法,您将有一些类型转换要做,这是很自然的。equals()

转换对象后,您无论如何都会检查 的每个元素,因此,如果它们属于不同的类型,它们也将无法进行相等性检查。Pair


查看完整回答
反对 回复 2022-09-22

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信