Javaでnullポインタ例外を回避する方法は?

Javaでnullポインターの例外を回避する方法も、ジュニアプログラマーが中級プログラマーに成長するときによく発生する問題です。

プログラマーは、使用されている規則を知らないか信頼しておらず、nullをチェックするように注意しています。また、プログラマーがコードを書くとき、彼らは常に何らかの意味を示すためにNULLを返すことに依存しているので、呼び出し元はNullをチェックする必要があります。

2つのnullポインタチェックシナリオがあります。

  1. 期待される結果はnullです。
  2. 期待される結果はnullではありません。

2つ目は非常に単純で、assertを使用するか、プログラムがNullPointerExceptionのスローなどのエラーを報告できるようにすることができます。アサーションは、Java 1.4から追加された非常に未使用の機能であり、構文は次のとおりです。

assert <condition>
复制代码

また

assert <condition> : <object>
复制代码

条件はブール式であり、オブジェクトはオブジェクトです(toString()メソッドの出力はエラーに含まれます)。

校正メモ:JDK1.4以降でテストし、実行する前にvmパラメーター-eaを設定しました

public static void main(String[] args) {String name = null;assert (name != null) : "name为空null";}
Exception in thread "main"; java.lang.AssertionError: 变量name为空nullat LogUtil.main(LogUtil.java:37)
复制代码

条件がfalseの場合、assertはエラー(AssertionError)をスローします。デフォルトでは、Javaはアサーションを無視します。-eaパラメーターをJVMに渡すことにより、アサーションを有効にできます。

単一のパッケージまたはクラスのアサーションを有効または無効にできます。これは、開発およびテスト中にアサーションを使用してコードを検証し、本番環境に出荷するときにオフにすることができることを意味します。ただし、以下に示すテストでは、アサーションによってパフォーマンスが低下することはありません。アサーションを追加するのと同じように失敗するため、このコードセグメントにアサーションがなくても問題ありません。唯一の違いは、アサーションを使用すると、より速く、より意味があり、失敗した理由を理解するのに役立つ追加情報を添付できる可能性があることです。

1つ目は少し注意が必要です。呼び出されているコードを制御できない場合は、行き詰まります。Nullが妥当な戻り値である場合は、それを確認する必要があります。制御できるコードであれば、まったく別の話です。戻り値としてNULLを使用しないようにしてください。コレクションを返すコレクションの場合、戻り値として常にnullを使用する代わりに、Empty(空のコレクションまたは配列)を返すのは簡単です。コレクションを返さないメソッドの場合は、もう少し複雑になります。次の例を考えてみましょう。

public interface Action {
  void doSomething();}public interface Parser {
  Action findAction(String userInput);}
复制代码

Parser采用用户的输入作为参数,然后做一些事情(例如模拟一个命令行)。现在你可能会返回null,如果没找到对应输入的动作的话,这就导致了刚才说过的空指针检查。

一个可选的解决方案是永远不要返回null,而是返回一个空对象

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }}
复制代码

比较这段代码:

Parser parser = ParserFactory.getParser();if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response}Action action = parser.findAction(someInput);if (action == null) {
  // do nothing} else {
  action.doSomething();}
复制代码

和这段:

ParserFactory.getParser().findAction(someInput).doSomething();
复制代码

这是个更好的设计,因为足够简洁,避免了多余的判断。

即便如此,或许比较合适的设计是:findAction()方法之恶杰抛出一个异常,其中包含一些有意义的错误信息—–特别是在这个案例中你依赖于用户的输入。

让findAction()方法抛出一个异常而不是简单的产生一个没有任何解释的NullPointerException 要好得多。

try {
    ParserFactory.getParser().findAction(someInput).doSomething();} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());}
复制代码

或者你认为try/catch 的机制太丑了,你的action应该跟用户提供一个反馈而不是什么都不做:

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }}
复制代码

Java学习视频分享

Java基础:

Java300集,Java必备优质视频_手把手图解学习Java,让学习成为一种享受

Java项目:

【Java游戏项目】1小时教你用Java语言做经典扫雷游戏_手把手教你开发游戏

【Java毕业设计】OA办公系统项目实战_OA员工管理系统项目_java开发

おすすめ

転載: juejin.im/post/7078234903019536420