如何告诉编译器两个对象是相同的 - 但未知 - 类(带有泛型)?

时间:2017-11-02 21:45:27

标签: java generics comparable

请考虑以下代码:

public class MyClass {

  public static void main(String[] args) {    
    Object o1 = getObject(Math.random());
    Object o2 = getObject(Math.random());
    if (o1.getClass().equals(o2.getClass()) { // two Cars or two Apples
      Comparable c1 = (Comparable) o1;
      Comparable c2 = (Comparable) o2;
      int x = c1.compareTo(c2); // unsafe
      System.out.println(x);
    )
  }

  public Object getObject(double d) { // given method that may not be changed
    if (d < 0.5) return (new Car()); // Car implements Comparable<Car>
    else return (new Apple()); // Apple implements Comparable<Apple>
  }

}

代码有效(给定类CatApple)但编译器会警告不安全操作,因为我使用compareTo而没有泛型。但是,我不知道如何解决这个问题,因为我不知道如何指定c1c2是相同的 - 但未知 - 类型(在if子句中) 。有什么方法(除了当然使用@SuppressWarnings)来解决这个问题吗?

我知道这里有一个类似的问题:How to tell Java that two wildcard types are the same? 但那里给出的答案似乎与提问者的背景有关。例如,它使用的键值映射在我的上下文中不存在。

5 个答案:

答案 0 :(得分:1)

由于条件if (o1.getClass().equals(o2.getClass()))保证两个对象属于同一个类, 忽略警告是安全的。你可以压制它。

但是,由于此时他们的类型为Object, 将它们投射到Comparable并不安全。 你可以通过一些小的调整使它更安全,使它们成为Comparable类:

public static void main(String[] args) {
    Comparable<?> o1 = getComparable(Math.random());
    Comparable<?> o2 = getComparable(Math.random());
    if (o1.getClass().equals(o2.getClass())) {
        // safe cast
        Comparable c1 = (Comparable) o1;
        Comparable c2 = (Comparable) o2;
        // safe comparison
        int x = c1.compareTo(c2);
        System.out.println(x);
    }
}

public Comparable<? extends Comparable<?>> getComparable(double d) {
    if (d < 0.5) return (new Car());
    return (new Apple());
}

答案 1 :(得分:0)

这里的问题是title('$\matrix{\textrm{Some text} \cr \sigma_{T}=\sigma_{D}=10^{-5}}$', ... 'Interpreter', 'latex'); Comparable<Car>无法相互比较,因为Comparable<Apple>只有比较Comparable<T>才具有“舒适”功能。而现在我们正在为此付出代价。

对于T,情况并非如此。

我们在尝试什么

.equals

这是java的一个特性,具有极低表现力的类型系统。

答案 2 :(得分:-1)

更新您的方法以处理Comparable个对象而不是Object个对象。

public class MyClass {

  public static void main(String[] args) {    
    Comparable o1 = getObject(Math.random());
    Comparable o2 = getObject(Math.random());
    if (o1.getClass().equals(o2.getClass()) { // two Cars or two Apples
      int x = o1.compareTo(o2);
      System.out.println(x);
    )
  }

  public Comparable getObject(double d) { // given method that may not be changed
    if (d < 0.5) return (new Car()); // Car implements Comparable<Car>
    else return (new Apple()); // Apple implements Comparable<Apple>
  }

}

答案 3 :(得分:-1)

另一种替代实施方式:

public static void main(String[] args) {    
    Object o1 = getObject(Math.random());
    Object o2 = getObject(Math.random());
    if ( o1.getClass().equals(o2.getClass() ) && o1 instanceof Comparable ) {
      int x = getObject(o1).compareTo(o2);
      System.out.println(x);
    }

  }

  public static Object getObject(double d) { // given method that may not be changed
    if (d < 0.5) return ( new Car() ); // Car implements Comparable<Car>
    else return ( new Apple() ); // Apple implements Comparable<Apple>
  }

  public static <T> Comparable<T> getObject(Object o) {
      return (Comparable<T>)o;
  }

答案 4 :(得分:-2)

您可以使用instanceof运算符。你可以把它写成:

if(c1 instanceof Integer && c2 instanceof Integer)
   int x = c.compareTo(c2);





or if(c1 instanceof String)
    String s = c1;

你可以这样工作。