美文网首页
项目27:消除未经检查的警告

项目27:消除未经检查的警告

作者: rabbittttt | 来源:发表于2019-06-07 16:15 被阅读0次

ITEM 27: ELIMINATE UNCHECKED WARNINGS
  使用泛型编程时,您将看到许多编译器警告: 未经检查的强制转换警告、未经检查的方法调用警告、未经检查的参数类型警告和未经检查的转换警告。使用泛型获得的经验越多,得到的警告就越少,但是不要期望新编写的代码能够干净地编译。
  许多未经检查的警告很容易消除。例如,假设您不小心编写了以下声明:
Set<Lark> exaltation = new HashSet();
  编译器会温柔地提醒你做错了什么:
“Venery.java:4: warning: [unchecked] unchecked conversion Set<Lark> exaltation = new HashSet(); required: Set<Lark> found: HashSet”
  我们应该按照指示更正,使警告消失。注意,实际上不需要指定类型参数,只需要指出它与在 Java 7 中引入的 diamond 操作符 (<>) 一起出现。编译器将推断正确的实际类型参数(在本例中为Lark):
Set<Lark> exaltation = new HashSet<>();
  有些警告更难消除。本章充满了此类警告的例子。当你得到需要一些思考的警告时,坚持下去!尽可能消除所有未经检查的警告。如果消除了所有警告,就可以确保代码是类型安全的,这是一件非常好的事情。这意味着您不会在运行时获得ClassCastException,并且它增加了您的信心,使您相信您的程序将按照您的意愿运行。
  如果不能消除警告,但是可以证明触发警告的代码是 typesafe,那么(而且只有在这种情况下)使用 @SuppressWarnings(“unchecked”) 注释来抑制警告。如果您在没有首先证明代码是类型安全的情况下就抑制了警告,那么您就给了自己一种错误的安全感。代码可以在编译时不发出任何警告,但仍然可以在运行时抛出ClassCastException。但是,如果忽略未检查的安全警告(而不是抑制它们),就不会注意到什么时候出现了一个表示真正问题的新警告。新的警告将在你没有保持沉默的所有错误警报中消失。
  SuppressWarnings 注释可以用于任何声明,从单个局部变量声明到整个类。始终在尽可能小的范围内使用 SuppressWarnings 注释。通常这将是一个变量声明或一个非常短的方法或构造函数。永远不要在整个类上使用 SuppressWarnings。这样做可能会掩盖严重的警告。
  如果您发现自己在一个方法或构造函数上使用了 SuppressWarnings 注释,并且该注释的长度超过一行,那么您可以将它移动到一个局部变量声明上。您可能需要声明一个新的局部变量,但这是值得的。例如,考虑这个 toArray 方法,它来自 ArrayList:

public <T> T[] toArray(T[] a) { 
  if (a.length < size)
    return (T[]) Arrays.copyOf(elements, size, a.getClass()); 
  System.arraycopy(elements, 0, a, 0, size);
  if (a.length > size)
    a[size] = null; 
  return a;
}

  如果编译 ArrayList,该方法将生成以下警告:
“ArrayList.java:305: warning: [unchecked] unchecked cast return (T[]) Arrays.copyOf(elements, size, a.getClass()); required: T[] found: Object[]”
  在 return 语句上放置一个 SuppressWarnings 注释是非法的,因为它不是一个声明[JLS, 9.7]。您可能想把注释放在整个方法上,但是不要这样做。相反,声明一个局部变量来保存返回值并注释它的声明,如下所示:

// Adding local variable to reduce scope of 
@SuppressWarnings
public <T> T[] toArray(T[] a) {
  if (a.length < size) {
  // This cast is correct because the array we're creating
  // is of the same type as the one passed in, which is T[].
    @SuppressWarnings("unchecked") T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass());
    return result;
  }
  System.arraycopy(elements, 0, a, 0, size); 
  if (a.length > size)
    a[size] = null; 
  return a;
}

  生成的方法干净地编译,并将抑制未检查警告的范围最小化。
  每次使用 @SuppressWarnings(“unchecked”) 注释时,添加一条注释说明为什么这样做是安全的。这将帮助其他人理解代码,更重要的是,它将减少有人修改代码以使计算不安全的几率。如果你觉得写这样的评论很难,请继续思考。您最终可能会发现,未检查的操作终究是不安全的。
  总之,未检查的警告很重要。不要忽视他们。每个未检查的警告都表示运行时可能出现 ClassCastException。尽最大努力消除这些警告。如果无法消除未检查警告,并且可以证明引发警告的代码是类型安全的,则使用 @SuppressWarnings(“unchecked”) 注释在尽可能小的范围内禁止警告。在评论中记录下你决定取消警告的理由。

相关文章

  • 项目27:消除未经检查的警告

    ITEM 27: ELIMINATE UNCHECKED WARNINGS  使用泛型编程时,您将看到许多编译器警...

  • 提示二十七

    提示二十七:消除非检查警告。 作者让我们尽可能消除每一个未经检查的警告,这样可以保证你的代码是类型安全的。如果你能...

  • iOS编译警告

    iOS编译警告-消除方法参数检查相关的警告 iOS编译警告-消除注释中的警告

  • Effective-java 3 中文翻译系列 (Item 27

    文章也上传到 github (欢迎关注,欢迎大神提点。) ITEM 27 消除 unchecked(未检查) 警告...

  • 消除Xcode编译警告

    最近项目做完了,开始进行优化,第一件事就是消除编译警告。编译警告虽然不会导致项目崩溃,但是看着烦。一边消除一边记录...

  • 消除Xcode 项目的警告

    在iOS开发过程中, 我们可能会碰到一些系统方法弃用, weak、循环引用、不能执行之类的警告。 有代码洁癖的很想...

  • iOS项目中消除警告⚠️

    最近把项目上线以后,难得空闲时间,每每看见项目中黄色的警告,便想到集中时间来把警告一一消除。下面是我在此过程...

  • iOS编译警告-消除方法参数检查相关的警告

    在 Build Settings 中将 Strict Prototypes 的warning开关关掉,就不会报方法...

  • 消除pod项目中的警告

    在podfile中添加: inhibit_all_warnings! platform :ios, "7.0"in...

  • 消除pod项目中的警告

    inhibit_all_warnings! 发现只能忽略一部分 不能全部忽略

网友评论

      本文标题:项目27:消除未经检查的警告

      本文链接:https://www.haomeiwen.com/subject/jjzmxctx.html