【问题标题】:Why is varargs (Class<? extends Throwable>... t) "unchecked or unsafe" operation?为什么 varargs (Class<? extends Throwable>... t) “未经检查或不安全”的操作?
【发布时间】:2013-02-13 09:51:58
【问题描述】:

好的,我正在调用带有签名(Class&lt;? extends Throwable&gt;... 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。感谢您的任何提示。

【问题讨论】:

  • 您确定警告来自thenThrow 而不是whenmockQuery 是如何声明的?它是泛型类的模拟吗?
  • 好的,我已将代码更改为可测试的示例。

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


【解决方案1】:

因为 varargs 实际上只是数组,而且generics and arrays don't mix(好吧),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 中完全禁用了通用可变参数警告,因为从调用者的角度来看,它们几乎从不指示错误的代码。

【讨论】:

  • 再次阅读您的答案,包括最后一段。谢谢!
  • 我也没有收到声纳警告也很奇怪。无论如何,我在方法上添加了@SuppressWarnings("unchecked")。再次感谢。
【解决方案2】:

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

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

只是

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

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

当然,new Class&lt;? extends Throwable&gt;[] 在 Java 中是不允许的。所以编译器会改为 new Class&lt;?&gt;[] 并给出警告。

【讨论】:

  • 感谢 newacct!我已经接受了马克的回答,但也感谢你添加你的回答。
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多