不能使用方法吗?

时间:2016-01-21 20:20:05

标签: java generics

我有一个用于实现通用Pair接口的赋值,该接口表示有序对,如(x,y)。我试图编写equals方法,但我必须将参数设为一般对象而不是一对,所以我不知道如何获取它的坐标。我尝试编译时遇到符号未找到错误,因为Object类没有fst和snd方法。我应该抛出异常吗?注意:我的教授给了我们一个模板,我只是填写方法,我不认为我可以改变参数或方法。

此处的相关代码:

    public class Pair<T1,T2> implements PairInterface<T1,T2>
{
private T1 x;
private T2 y;

public Pair(T1 aFirst, T2 aSecond)
{
    x = aFirst;
    y = aSecond;
}

/**
 * Gets the first element of this pair.
 * @return the first element of this pair.
 */
public T1 fst()
{
    return x;
}

/**
 * Gets the second element of this pair.
 * @return the second element of this pair.
 */
public T2 snd()
{
    return y;
}

...

    /**
 * Checks whether two pairs are equal. Note that the pair
 * (a,b) is equal to the pair (x,y) if and only if a is
 * equal to x and b is equal to y.
 * @return true if this pair is equal to aPair. Otherwise
 * return false.
 */
public boolean equals(Object otherObject)
{
    if(otherObject == null)
    {
        return false;
    }

    if(getClass() != otherObject.getClass())
    {
        return false;
    }
    T1 a = otherObject.fst();
    T2 b = otherObject.snd();
    if (x.equals(a) && y.equals(b))
    {
        return true;
    }
    else 
    {
        return false;
    }
}

这些是我得到的错误:

    ./Pair.java:66: cannot find symbol
    symbol  : method fst()
    location: class java.lang.Object
    T1 a = otherObject.fst();
                      ^
    ./Pair.java:67: cannot find symbol
    symbol  : method snd()
    location: class java.lang.Object
    T2 b = otherObject.snd();
                      ^

7 个答案:

答案 0 :(得分:4)

equals方法的参数是Object,不保证您的方法fstsnd,因此编译错误。为了能够调用这些方法,您需要有一个Pair对象。

标准做法是测试传入的对象的类,看看它是否与this相同,如果它不是同一个类,则返回false。通常用instanceof完成,然后按true进行投射。强制转换允许编译器将对象视为您所说的类。这允许编译器找到您要调用的方法。

if(otherObject == null)
{
    return false;
}

// Use instanceof
if(!(otherObject instanceof Pair))
{
    return false;
}
// Cast - use <?, ?>; we don't know what they are.
Pair<?, ?> otherPair = (Pair<?, ?>) otherObject;
Object a = otherPair.fst();
Object b = otherPair.snd();
// Simplified return
return (x.equals(a) && y.equals(b));

答案 1 :(得分:0)

课后比较if(getClass() != otherObject.getClass()) return false;

您需要使用正确的类型创建新变量,如下所示:

Pair<T1,T2> pair = (Pair<T1,T2>)otherObject;

然后您就可以使用pair及其方法

答案 2 :(得分:0)

在调用其方法之前将其他对象转换为一对。

Pair<T1, T2> otherPair = (Pair) otherObject;
T1 a = otherPair.fst();
T2 b = otherPair.snd();

答案 3 :(得分:0)

这是因为你没有先抛出otherObject,所以JVM认为它是Object类型。一个对象没有方法fst()和snd(),所以它失败了。

要解决,请将otherObject强制转换为Pair,然后调用fst()和snd():

public boolean equals(Object otherObject)
{
    if(otherObject == null)
    {
        return false;
    }

    if(getClass() != otherObject.getClass())
    {
        return false;
    }


    T1 a = ((Pair<T1, T2>)otherObject).fst();
    T2 b = ((Pair<T1, T2>)otherObject).snd();
    if (x.equals(a) && y.equals(b))
    {
        return true;
    }
    else 
    {
        return false;
    }
}

答案 4 :(得分:0)

确保getClass() != otherObject.getClass()成立后,您可以对Pair<?, ?> pair = (Pair<?, ?>) otherObject;执行安全演员。然后,按原样使用您的代码。 注意:您无法对Pair<T1, T2>执行安全转换,因为您只知道otherObject是Pair<?, ?>的实例。但是,与.equals()的比较仍应有效。

答案 5 :(得分:0)

你必须首先明确地将另一个对象强制转换成一对(考虑到你已经知道它是Pair对象因为类是相同的),但是你不知道是什么键入它,所以你应该使用外卡。

Pair<?, ?> otherPair = (Pair<?, ?>)otherObject;
//add null-checks if fst() or snd() is nullable
if(this.fst().equals(otherPair.fst()) && this.snd().equals(otherPair.snd()) {
    return true;
} else {
    return false;
}

答案 6 :(得分:0)

您可以将任何对象类型传递给equals(),因此正确实现equals的一部分是检查参数Object的类型。

如果你看一下java核心类,它们通常先检查==然后是否是实现equals()的类的实例。

一般来说,你应该检查: 1)==相等,即参数是否是对当前对象本身的引用 - 如果是,则对象应该等于每个等于()。这在计算上很便宜。 2)参数是否为空。这在计算上也很便宜,如果是,则确保equals()返回false。 3)参数对象是否是当前对象类的实例。如果不是它就不能相等而且无论如何都会失败。 4)然后投射并开始将各部分相互比较

懒惰的程序员tipclipse可以使用向导自动生成漂亮的java equals()块。它是右键单击&gt;来源&gt;生成hashcode()equals()和bam,它生成一个正确的equals()方法。