【问题标题】:How to resolve unchecked call to compareTo(T) without using generics in Java如何在不使用 Java 泛型的情况下解决对 compareTo(T) 的未经检查的调用
【发布时间】:2019-03-09 17:38:53
【问题描述】:

我想解决这个编译器警告:

unchecked call to compareTo(T) as member of the raw type java.lang.Comparable

我的目标是使用以下方法比较两个未知(背景)类型的 java.lang.Object 对象。

public static boolean Compare(Object o1, Object o2) {
    //check if both classes are the same
    if(!o1.getClass().equals(o2.getClass())) {
       return false;
    } 

    if(Comparable.class.isAssignableFrom(o1.getClass()) 
        && Comparable.class.isAssignableFrom(o2.getClass())) {
       //only if both objects implement comparable
       return Comparable.class.cast(o1).compareTo(Comparable.class.cast(o2)) == 0;

    }
    //other comparison techniques...
}

我知道问题在于该方法将两个对象都转换为Comparable (Comparable<Object>),但Object 没有实现Comparable

代码本身可以工作,但编译器在使用 -Xlint:unchecked 参数时会抛出警告。

目标:

  • 删除编译器警告
  • 避免出现其他“未经检查”的警告
  • 避免使用@SupressWarning
  • 保持比较方法非泛型

【问题讨论】:

  • 你不能。 SuppressWarning 正是为此:编译器警告你你正在做一些它无法检查它是否是类型安全的事情。要么让你的代码类型安全,要么告诉编译器:我知道,我知道,请相信我。这就是 SuppressWarning 的用途。不过,您应该尊重 Java 约定。这很简单,而且不涉及禁止警告。
  • 如果你不知道这两个类是否实现了Comparable,那么比较它们是没有意义的。顺便说一句,看起来你尝试实现equals
  • @JB Nizet - 谢谢,看来我会使用 SupressWarning。
  • @Lutz Horn - 我没有实现 equals,我只是想比较两个使用反射动态调用的方法的结果。

标签: java generics comparable unchecked


【解决方案1】:

您不能轻易逃避编译器警告。它的工作是告诉您何时进行可能在运行时中断的类型操作。实现目标的唯一方法是进行更多未经检查的操作,如下所示:

    if(Comparable.class.isAssignableFrom(o1.getClass()) 
            && Comparable.class.isAssignableFrom(o2.getClass())) {
        // Cache this somewhere if you're really going to use it
        Method compareTo = Comparable.class.getMethod("compareTo", Object.class);
        Integer result = (Integer) compareTo.invoke(o1, o2);

        return result == 0;

    }

最好的选择仍然是在转换对象时使用一次@SuppressWarnings,然后继续使用它。如果你不能保证参数的类型安全,使用它是完全可以的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多