Java配列で、要素にnullが指定されているのに、NullPointerExceptionになるケースとならないケースの差がわかりません
インプレス社 Java SE Silver 8の問題集の第四章 項5と項6で、一見相反するかのような正答があり混乱しています。
その箇所を抜き出すと次のような感じです。
項5 次のプログラムをコンパイル、実行したときの結果として、正しいものを選びなさい(一つ選択)
public class Item {
String name;
int price = 100;
}
public class Main{
public static void main(String[] arigs){
int total = 0;
for (int i = 0; i < items.length; i++){
total += items[i].price;
}
System.out.println(total);
}
}
A.0が表示される。
B.200が表示される。
C.300が表示される。
D.コンパイルエラーが発生する
E.実行時に例外がスローされる
項6 次のプログラムをコンパイル、実行したときの結果として、正しいものを選びなさい(一つ選択)
public class Main{
public static void main(String[] args){
String[] array = {"A","B","C","D"};
array[0] = null;
for (String str : array){
System.out.print(str);
}
}
}
A.「ABCD」と表示される。
B.「BCD」と表示される。
C.「nullBCD」と表示される。
D.「null」と表示される。
E.コンパイルエラーが発生する。
F.実行時にエラーがスローされる。
尚、上記の項5の正解はEで、項6の正解はCとありました。
それぞれの理由を記載すると、
項5:
Item[] items = new Item[3];の時点で配列インスタンスは生成したが、Itemのインスタンスを生成したわけではないので、全てnullが入っている。
配列の中での各要素の参照先が存在しないため、NullPointerExcetptionが発生する。
項6:
配列インスタンスの4つの要素は「null」と「B、C、DのStringインスタンスの参照」です。そのため、コンソールには「nullBCD」と表示されます。
とのことで、nullに対する扱いが理解できません。
類推するに、項5ではnullを明示的に入れておらず、項6ではnullを明示的に入れているので、配列インスタンスを生成しただけで、中身のオブジェクトは入れていないという状態での、要素の中の状態は参照先が無いと思っているのですが、これは明示的にnullを指定するケースと異なると言うことなのでしょうか(私の中では要素の中で参照先がない状態と、明示的にnullを要素指定した場合は同一だと思っているのですが、この認識が誤っているのでしょうか)。
もしくはString型だけ特別扱いで、nullが指定されていればnullと表示してくれるのでしょうか。
No.4ベストアンサー
- 回答日時:
「そもそもNullPointerExceptionってそんなものだから。
」としか言いようがありません。まずそもそもNullPointerExceptionはnull pointer exceptionではありません。
null pointer's sub field or method reference exceptionです。
つまりですね、null値を参照しただけでは発生しません。
null値のフィールドやメソッドを参照した時に初めて発生します。
#ネーミングセンスどうよとは思いますが正確を期すと名前が長すぎて例外処理を書く度にFワードを吐く事になるので致し方ないです。
では各項に当てはめて行きます。
項4の場合は下に示した行でNullPointerExceptionが発生します。
total += items[i].price;
items[i]がnull値でnull値のpriceを参照しようとしてNullPointerExceptionとなります。
一方項5の場合は、System.out.pintの中身と関係があります。
ざっくりといろいろ省略して以下の様な感じです。
#但しシステムのPrint関数をSysPrintとして表記します。
void print(Object value){
if(value==null){
SysPrint(”null”);
}else{
SysPrint(value.ToString());
}
}
null値を参照しますが、null値のフィールドやメソッドは参照していません。
ですから例外は発生しないしません。
なるほど!
分かりやすい説明ありがとうございました。
nullが来てもヌルポで落ちないように特別扱いしているんですね。
これで理解できました。
No.5
- 回答日時:
Sytem.out.print は null を受けとると "null"と表示する「仕様」になっている。
それだけですよ。
No.3
- 回答日時:
そもそもプリミティブ型だと null が存在しない... けど, 今回とは関係ない話.
項5 と項6 のプログラムを, それぞれ
5'
public class Item {
String name;
int price = 100;
}
public class Main{
public static void main(String[] arigs){
Item[] items = new Item[3];
for (int i = 0; i < items.length; i++){
System.out.println(items[i]);
}
}
}
6'
public class Main{
public static void main(String[] args){
String[] array = {"A","B","C","D"};
array[0] = null;
int len = 0;
for (String str : array){
len += str.length();
}
System.out.println(len);
}
}
としたらどうなるかわかりますか?
>プリミティブ型だと null が存在しない
なるほど・・・不勉強でした。一つ勉強になりました。ありがとうございます。
例題もありがとうございます。
これはこれまでの文脈からすると、(私の頭の中ではヌルポで落ちると思っていましたが)
No.5の方は、
System.out.println(items[i]);
の部分で三回
null
null
null
と出力されるとおもいます。
No.6の方は、事前に配列の中身も入っているので、特にエラーになることもなく
str.length()の4が拡張for文の中で4回足しこまれて
最後の
System.out.println(len);
で16が出力されるように思います。合っていますか?
No.1
- 回答日時:
項5 って, これだと「コンパイルエラーが発生する」が正しいのでは? 下には
Item[] items = new Item[3];の時点で
って書いてあるけど, こんな文はどこにもないですよ.
さておき, 項5 では「null が参照するインスタンス」にアクセスしてるけど, 項6 では「null が参照するインスタンス」にはアクセスしなくていいよね.
まあ System.out.println が null を特別扱いしてるのも事実.
すみません、肝心の問題文に誤りがありました。
項5は
public class Item {
String name;
int price = 100;
}
public class Main{
public static void main(String[] arigs){
Item[] items = new Item[3];
int total = 0;
for (int i = 0; i < items.length; i++){
total += items[i].price;
}
System.out.println(total);
}
}
となります。大変失礼しました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
家の中でのこだわりスペースはどこですか?
自分の家で快適に過ごすために工夫しているスペースはありますか? 例)ベランダでお茶を飲むためのカフェテーブル ゲーミングに特化したこだわりのPCスペース
-
チョコミントアイス
得意ですか?不得意ですか?できれば理由も教えてください。
-
CDの保有枚数を教えてください
ひとむかし前はCDを買ったり借りたりが主流でしたが、サブスクで簡単に音楽が聴ける今、CDを手に取ることも減ってきたかと思います。皆さんは2024年現在、何枚くらいCDをお持ちですか?
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
あなたの習慣について教えてください!!
あなたが習慣だと思って実践しているものを共有してくださいませんか? 筋肉トレーニングでも朝シャワーでも、あなたが習慣だなと思えば何でも構いません
-
配列にnullを代入すると、nullが文字列として出力されるんですが何故ですか? int a[] =
Java
-
servletからjspへオブジェクトの配列情報を送る方法
Java
-
Path型をString型へ変換する(Java)
Java
-
-
4
Oracle 2つのDate型の値の差を「分」で取得したい
その他(データベース)
-
5
[JAVA]try 内の変数を外で!?
Java
-
6
JSPの処理の途中で、JavaScriptの処理をしたい
JavaScript
-
7
tableタグとformタグの組み合わせ
HTML・CSS
-
8
DTOとEntityの差は何ですか。
Java
-
9
eclipseのショトカットキー
Java
-
10
インスタンスを同じ名前で作成できる?
Java
-
11
無名配列の作成方法について質問
Java
-
12
Eclipseで、プロジェクト名のところに赤いバッテンのエラーマークが
Java
-
13
エスケープ文字の復帰(¥r)とはなんですか?
Java
-
14
Java-jspの画面入力値保持について
Java
-
15
Eclipse(JAVA)のデバッグで他のプログラムが起動してしまいます。
Java
-
16
リクエストに応じたselectedの初期値設定方法
Java
-
17
変数を動的に利用するには?
Java
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ORA-01858: 数値を指定する箇所...
-
C# ListBoxのインデックスの値...
-
Java配列でNullPointerExceptio...
-
getStringの値がNULLの時の処理
-
hiddenの値が期待した値で取得...
-
大量のデータを読み込んで表示...
-
パソコンキーボードで時分秒を...
-
VBAで配列の計算
-
C#の質問
-
JAVAのfor文で困っています。
-
Java 入力した整数値の合計を、...
-
変数を動的に作るには?
-
演算子 ^ は double,double に...
-
ダブルクォーテーションのrepla...
-
1~100までの数字を表示し、か...
-
java プログラミングについて
-
iPhoneでのjavascriptで音を出...
-
var now = +new Dateの +は何?
-
IF関数でEmpty値を設定する方法。
-
java 素数判定について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ORA-01858: 数値を指定する箇所...
-
BOOL値を逆にしたい
-
Java配列でNullPointerExceptio...
-
配列にnullを代入すると、null...
-
getStringの値がNULLの時の処理
-
androidアプリが強制終了してし...
-
例外でBeanUtils.populateが、...
-
C# ListBoxのインデックスの値...
-
eclipseでoracle接続時のエラー...
-
HashMapがおかしい
-
C#でラジオボタンとコンボボッ...
-
Tomcatを再起動するとエラーが...
-
gas カレンダー祭日設定でエラー
-
java DAO 日付指定フォーマット...
-
逆コンパイルの見方について(...
-
Stringを返す getText()メソッ...
-
if文を通らない
-
JSPによる画面間のパラメータの...
-
Safari ダウンロード時に日本語...
-
JSPでの画面表示の方法
おすすめ情報
すみません、肝心の問題文に誤りがありました。
項5は
public class Item {
String name;
int price = 100;
}
public class Main{
public static void main(String[] arigs){
Item[] items = new Item[3];
int total = 0;
for (int i = 0; i < items.length; i++){
total += items[i].price;
}
System.out.println(total);
}
}
となります。大変失礼しました。