yuhi58587
@yuhi58587

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

NullPointerExceptionがスローされるタイミング

Q&A

Closed

NullPointerExceptionがスローされるタイミングについて

黒本を解いていて実行結果が「null」が返される場合と、「NullPointerException」がスローされる時があります。「NullPointerException」がスローされる条件は何ですか?

該当するソースコード(例)

public class Main {
  public static vooid main(String[] args) {
    try {
      String[] array = new String[5];
      array[1] = "A";
      array[2] = "B";
      array[3] = "C";
      for (String str : array) {
        System.out.println(str);
      }
    } catch (Exception e) {
      System.out.println("Error");
    }
  }
}

//実行結果
null A B C null

自分で試したこと

他の方のQiitaの記事や公式ドキュメントを読んだりし、調べた結果としては、

null値の参照型変数を参照しようとした時に発生する例外
参照型変数

  • 配列型(sample[],、String[])
  • クラス型(String型、List型、Map型、Set型)
  • インターフェース型

というものが出てきました。ですが、上記のコードのように配列型やクラス型を使用しているが「NullPointerException」がスローされていないためイマイチ理解できていません。
拙い文章ですが、ご教示頂けたらと思います。

0

1Answer

null値の参照型変数を参照しようとした時に発生する例外
この説明の中の参照しようとという部分の表現が誤解を招きそうな部分だと思っていますが、提示いただいた以下コードは、参照というよりは変数の値を標準出力をする(参照ではない)ので、変数の値がnullであれば、nullとコンソールに表示されます。

System.out.println(str);

参照とはどういった操作か

以下の3つがよくある例だと思います。
(ちょっと検索していただければ、ヒットすると思います)

1.nullオブジェクトのフィールドに対してアクセスまたは変更を試みた場合
2.nullオブジェクトのメソッドの呼び出しを試みた場合
3.nullの配列やリストの大きさ取得や、N番目の値の取得といった操作を試みる場合

1と2について

以下のようなクラスを仮で用意してみます。

public class Sample {

  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void helloWorld() {
    System.out.println("HelloWorld");
  }

}

mainメソッドがあるクラスで以下のように実装すれば、2,3行目のコードは、java.lang.NullPointerExceptionになります。
(例を提示するために一緒に記載してますが、2行目でExceptionが発生するので、3行目は実行されません)

Sample sample = null;
sample.getName();
sample.helloWorld();
3について

以下のように、null値の配列やリストを用意して、大きさを取得しようとすると、java.lang.NullPointerExceptionになります。
(N番目の要素取得の方は、省略します)

//配列
String[] sampleArr = null;
System.out.println(sampleArr.length);
// リスト
List<String> strList = null;
System.out.println(strList.size());

こんな回答でいかがでしょうか。

3Like

Comments

  1. @yuhi58587

    Questioner

    とてもわかりやすい回答ありがとうございます。
    System.out.printlnはあくまでも出力するというだけで、参照は行なっていない。getterメソッドやsetterメソッドなどで変数の呼び出しを行ったり、配列型変数で変数(この場合だとnull)の情報を取得しようとするとNullPointerExceptionがスローされる。という認識であっていますでしょうか。

  2. その認識でOkだと思います!!

  3. @yuhi58587

    Questioner

    ありがとうございます。きちんと理解することができました!:bow_tone1:

  4. System.out.println(Object)は内部的にはString.valueOf(Object)を読んでいます. このメソッドのAPIドキュメント(下記)を見ると, nullの場合に例外をスローしないように特別な処理をしていることがわかると思います.

Your answer might help someone💌