@SuppressWarnings("unchecked") 的放置位置是否重要?

7

我曾使用过@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")移到SomeClass类的上一行,如下所示:

@SuppressWarnings("unchecked")
class SomeClass {

两个错误信息神奇地消失了,这让我感到困惑不已。 @SuppressWarnings("unchecked") 的位置是否如此关键?


@SuppressWarnings 用于抑制任何警告的抛出。 - Kyle Emmanuel
是的,@SuppressWarnings注释非常重要。如果没有它,编译器会发出有关不安全操作的警告。您可以查看此链接:http://www.codejava.net/java-core/the-java-language/suppresswarnings-annotation-examples - user6554564
3个回答

9

您不能在语句中放置诸如@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 方法的警告,而不是整个类的警告。
您甚至可以将其放在变量 声明 上,但绝不能放在语句中:
@SuppressWarnings("unchecked")
Vector v = new Vector();

然而,正如GhostCat所指出的那样,在这种情况下,最好只是将向量泛化,而不是忽略警告。

谢谢你的建议“可能最好是将向量泛型化,而不是忽略警告”。我想使用向量v来收集不同类型的元素。因此,我没有将其泛型化的选项。 - Seshadri R
@SeshadriR 你可以使用 Vector<Object>。然而,ArrayList<Object> 更加可取。 - Michaela Elschner

3
可以这样说:你不能在语句(如 v.add(1))上放置此注解,而应该在声明上使用。但是这种答案会忽略太多重要的方面。
事实上,您可以使用注释来防止编译器发出警告。另一方面,您只想抑制那些您理解并且认为“可以被抑制”的警告。
从这个角度出发,您总是要在“最小”的级别上注释。因此,注释应该放在这里:
@SuppressWarnings("unchecked")
Vector v = new Vector();

当然,在你的情况下,警告是绝对有效的,抑制它是错误的。只需将您的代码更改为:
Vector<Integer> v = new Vector<>();

嗨,不用再使用注释了。

换句话说:你需要从“里到外”逐步解决问题。也就是说,如果你需要消除警告,你首先要找到引起警告的单个变量。只有当一个方法中有太多这样的语句时,你才会在方法上放置注释。你永远不想注释整个类。因为那将抑制整个类中所有这样的警告。

老实说:这里真正学到的教训是:学习你正在使用的概念。编译器发出警告是因为你正在使用一个原始类型(通过省略声明v时的类型参数)。然后忽略这个警告是错误的错误的错误的。你需要弄清楚警告告诉你什么,然后修复你的代码!

“好的代码”完全没有警告;而且尽可能少地使用“抑制”注释!


+1 指出了“真正”的解决方案,但您可能还应该指出为什么它不能放在陈述中。 - Michaela Elschner

1

是的,这个注释的放置位置和其他注释一样重要,这由注释@Target在该注释本身的定义中定义。

对于@SupressWarnings,它是

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

但是您将其放置在一个不属于上述范围的语句上。您至少应该将其放置在局部变量声明级别上:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接