12

好的,所以我正在调用带有签名的方法,(Class<? extends Throwable>... exceptions)并且在主方法中收到“File.java 使用未经检查或不安全的操作”警告:

public class VarargsFun {
    public void onException(Class<? extends Throwable>... exceptions) { }

    public static void main(String[] args) {
        new VarargsFun().onException(IllegalArgumentException.class);
    }
}

编译器不应该能够看到IllegalArgumentException确实扩展了RuntimeExceptionException并且Throwable

我应该如何正确修改我的代码以消除此警告?

我真的不想实例化我的异常......使用.class

(也不想使用@SuppressWarnings!)

我正在使用 java 7。感谢您的任何提示。

4

2 回答 2

13

因为 varargs 实际上只是数组,并且泛型和数组不能混合(很好),Java 传统上在调用具有泛型 vararg 类型的方法时会给出警告。这是因为从技术上讲,数组是在调用者处创建的。

然而,从调用者的角度来看,仅仅为了传递给可变参数方法而创建的数组并没有像普通的泛型数组那样遭受同样的危险,但是接收泛型数组的方法本身可能会滥用它们。所以在 Java 7 之前,警告出现在方法本身(在你的情况下,onException),并且可以通过使用@SafeVarargs方法上的注释来抑制:

@SafeVarargs
public void onException(Class<? extends Throwable>... exceptions) { }

如果您实际上没有使用 Java 7 语言,或者您无法更改onException(可能是因为它是一种库方法),那么您可以安全地使用@SuppressWarnings来隐藏该警告:

@SuppressWarnings("unchecked")
public static void main(String[] args) {
    new VarargsFun().onException(IllegalArgumentException.class);
}

但是,如果您以这种方式抑制警告,请注意将这一语句隔离在其自己的方法中,这样您就不会意外地抑制其他未来的警告。

就个人而言,我在我的 IDE 中完全禁用了通用可变参数警告,因为从调用者的角度来看,它们几乎从不指示错误的代码。

于 2013-02-27T14:46:07.700 回答
12

如果您意识到这一点,则最容易理解

new VarargsFun().onException(IllegalArgumentException.class);

只是语法糖

new VarargsFun().onException(
    new Class<? extends Throwable>[]{ IllegalArgumentException.class });

即调用站点创建一个组件类型等于可变参数类型的数组。

但当然,new Class<? extends Throwable>[]在 Java 中是不允许的。所以编译器new Class<?>[]会这样做并给出警告。

于 2013-02-27T19:39:59.370 回答