在代码中使用抑制警告是一种好习惯吗?


11

我用@SuppressWarnings("unchecked")@SuppressWarnings("null")大多上面的方法,让没有任何警告的代码编译,但我有我的怀疑。找到了这个Stackoverflow 问题。乔恩·斯基特(Jon Skeet)为此回答了一个有趣的答案

据他介绍,

有时Java泛型只是不允许您做您想做的事情,您需要有效地告诉编译器在执行时所做的事情实际上是合法的。

但是,如果有机会引发异常该怎么办?那抑制警告不是一个坏主意吗?我是否应该知道可能出现问题的地方?

另外,如果其他人稍后修改了我的代码并添加了一些可疑的功能却又没有删除SuppressWarnings,该怎么办?如何避免和/或有其他替代方法?

我应该使用@SuppressWarnings("unchecked")@SuppressWarnings("null")吗?


更新#1

对于未检查的类型强制转换,根据此答案(由@gnat在下面的注释中指出),有必要抑制这些警告。

许多必不可少的Java库从未进行过更新,以消除对不安全类型转换的需求。抑制这些警告是必要的,以便其他更重要的警告将被注意到并得到纠正。

在禁止其他警告的情况下,仍在灰色区域中。


更新#2

根据Oracle文档(以下一些答案也提到):

作为样式问题,程序员应始终在最有效嵌套的最深层元素上使用此注释。如果要在特定方法中禁止显示警告,则应注释该方法而不是其类。



@gnat他们不谈论未经检查的类型转换cast
Bilesh Ganguly

1
他们这样做:“许多不可或缺的Java库从未进行过更新,以消除对不安全类型转换的需要。抑制这些警告是必要的,这样其他更重要的警告也将得到注意和纠正。”
蚊蚋

2
我认为重复的问题与C#有关-有一些特定于Java的原因与抑制编译器警告的一般思想不同。

Answers:


26

对我而言,抑制警告的全部目的是为您的项目维护“干净的健康单”。如果您知道整个代码库都可以正常编译,那么当有人做错了导致第一个警告出现在问题列表中时,就会立即显而易见。然后,如果可以证明错误是虚假的,则可以修复该错误或将其排除。

但是,如果您一开始就有21条警告,那么很有可能在有人引起警告时您会忽略第22条警告,并且您不会检查它是否无害。这意味着问题会蔓延到您的代码库中,您永远不会注意到。

警告是有用的信息。确保您注意那些讲真话的人,并过滤掉那些不讲真话的人。不要让人们将两者混为一谈,以免失去预警系统。

编辑

我可能应该澄清,抑制确实有优点的警告是一件愚蠢的事情。通过作弊获得健康的健康账单显然一文不值。在做出选择之后,您应该始终解决编译器注意到的问题,而不是仅仅视而不见。但是,在某些区域中,编译器无法确定是否会出现问题(Java的泛型就是其中一个区域),更好的选择是查看每个此类实例,然后在此特定位置隐藏警告,而不是而不是完全关闭此类警告并有可能错过真正的警告。


1
我部分同意,从“干净”的清单开始可以帮助您捕获以后的警告,事实是干净地编译的代码可能无法干净地运行。
user949300 2013年

我在工作中遇到的问题是,我经常遇到警告,其他人因为他们不明白该说什么而压制了警告。因此,我想警告是否有根据是主观的。:/
Trejkaz

16

禁止警告是需要格外小心的事情。

警告的意思是:编译器发现某些东西看起来很狡猾。这并不意味着它狡猾的,只是在编译器中看起来像它。有时,您的代码完全正确,并发出警告。有时您可以通过稍微修改代码来修复它。有时,编译器具有一些专门用于此目的的功能。例如哪里

if (x = someFunction ()) { ... }

发出警告,但

if ((x = someFunction ())) { ... }

没有。在第一种情况下,警告提示您可能表示==而不是=。在第二种情况下,没有警告,因为多余的括号告诉编译器“我知道我在做什么”。更好的当然是

if ((x = someFunction ()) != 0) { ... }

或使用两行。

有时,在极少数情况下,您的代码可以正常运行,但是您无法以无警告的方式接受编写代码。在那种非常罕见的情况下,您可以禁用该语句的警告,然后立即将其打开。那是不得已的方法。而且您只禁用该特定警告,而没有其他警告。

但是,有些人只是禁用警告以摆脱警告,因为他们懒得先找出并解决发出合法警告的原因。否则,他们甚至不会尝试编写没有警告的代码。这是非常不健康的事情。


2
我认为您可能在第二个和第三个示例中缺少一些右括号。
8bittree '16

1
完全同意最后一句
USR-本地ΕΨΗΕΛΩΝ

7

怀疑对整个方法都发出警告。最好用注释取消显示特定行的警告。例如

@SuppressWarnings("unchecked") Foo foo = (Foo)object; // Using old library requires this cast

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.