为什么varargs(Class <! - ?extends Throwable - > ... t)&#34; unchecked or unsafe&#34;操作?

时间:2013-02-27 14:32:52

标签: java exception generics compiler-warnings variadic-functions

好的,所以我正在调用带有签名(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确实扩展RuntimeExceptionExceptionThrowable

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

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

似乎更好

(不想使用@SuppressWarnings!)

使用java 7.感谢任何提示。

2 个答案:

答案 0 :(得分:13)

因为varargs实际上只是数组,而generics and arrays don't mix(well),所以当您使用泛型vararg类型调用方法时,Java传统上会发出警告。这是因为从技术上讲,数组是在调用者处创建的。

然而,很快就发现,仅仅传递给varargs方法的数组并没有像调用者的视角那样遭受与普通通用数组相同的危险,但是接收到的方法本身通用数组可能会滥用它们。因此,在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中完全禁用了通用的vararg警告,因为从调用者的角度来看,它们几乎从不表示错误的代码。

答案 1 :(得分:11)

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

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

只是

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

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

但当然,Java中不允许使用new Class<? extends Throwable>[]。因此,编译器会执行new Class<?>[]并发出警告。