@SuppressWarnings("unchecked") 的位置重要吗?

Does the placement of @SuppressWarnings("unchecked") matter?

我用过 @SuppressWarnings("unchecked") 比如:

class SomeClass {
  public static void main(String [] args) {
    Vector v = new Vector();
    @SuppressWarnings("unchecked")
    v.addElement(new Integer(1_000_000));
    // ...        

使用javac 8.0版本编译时,出现如下错误:

error: <identifier> expected
        v.addElement(new Integer(1_000_000));

插入符号 (^) 指向 addElement 方法的左括号,还有一条错误消息抱怨缺少分号 (;)。第二条消息显示 addElement.

右括号附近的插入符

但是,当我将 @SuppressWarnings("unchecked") 移动到 class SomeClass{ 行上方时,如:

@SuppressWarnings("unchecked")
class SomeClass {

两条错误消息都自动消失了。这让我百思不得其解。 @SuppressWarnings("unchecked")的定位有那么挑剔吗?

您不能在声明中放置像 @SuppressWarnings("unchecked") 这样的注释,而只能在声明中放置。

这就是编译器不理解第一个变体的原因:

@SuppressWarnings("unchecked")
v.addElement(new Integer(1_000_000));

那里是非法的,编译器不会理解它。

如果你想缩小范围,你可以把它放在方法上:

@SuppressWarnings("unchecked")
public static void main(String [] args) {
    Vector v = new Vector();
    v.addElement(new Integer(1_000_000));

因此,只有 main 方法的警告会被忽略,而不是整个 class.

您甚至可以将其放在变量 声明 上,但绝不能放在语句上:

@SuppressWarnings("unchecked")
Vector v = new Vector();

但是,正如 GhostCat 指出的那样,在这种情况下,最好只是生成向量而不是忽略警告。

有人会说:你不能把这个注解放在语句上,比如v.add(1);相反,它应该继续声明,但这个答案会遗漏这里的许多重要方面。

事情是:一方面你可以使用注释来防止编译器给你警告。另一方面,您只想抑制那些您了解并考虑 "ok to be suppressed" 的警告。

从这个角度来看,您总是可以在 "smallest" 级别上进行注释。因此,注释将放在这里:

@SuppressWarnings("unchecked")
Vector v = new Vector();

但是当然,在您的情况下,警告 绝对 有效;并且抑制它是错误的

只需将您的代码更改为:

Vector<Integer> v = new Vector<>();

瞧瞧,根本不再需要注释了。

换句话说:您从 "in to out" 开始工作。意思是:如果你需要抑制警告,你首先要找到给你警告的个别 variables。并且只有当你在一个方法中有太多这样的语句时,你才把注释放在 方法 上。你永远不想注释整个 class。因为这会在整个 class 中抑制所有此类警告。

老实说:真正的 在这里学到的教训:研究 您正在使用的概念。编译器向您发出警告,因为您使用的是 raw 类型(通过在声明 v 时省略类型参数)。然后忽略那个警告是错错错。您弄清楚警告在告诉您什么,然后改正您的代码!

"Good code" 完全没有警告;并且它有尽可能少的 "suppress" 注释!

是的,此注释的放置与任何其他注释一样重要,这是由用于定义此注释本身的注释 @Target 定义的。

对于 @SupressWarnings 它是

@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})

但是你把它放在了一个不属于上述的声明中。您至少应该将它放在局部变量声明级别:

@SuppressWarnings("unchecked")
Vector v = new Vector();