オートボクシングの落とし穴
Nullのアンボクシングと==の落とし穴を学びます
「オートボクシングの落とし穴」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
便利さには落とし穴があります
オートボクシングによってコードはすっきりしますが、予想外のバグにつながる変換が隠れてしまいます。特に大きな落とし穴は、nullのアンボクシングと==による同一性比較の2つです。
このレッスンでは、その両方を避ける方法を説明します。
nullのアンボクシングの落とし穴
ラッパーがnullを保持している状態で、それをプリミティブ型にアンボクシングすると、JavaはNullPointerExceptionをスローします。
コードが単純な代入に見えるため、この問題は見落としやすいものです。
public class Main {
public static void main(String[] args) {
Integer maybe = null;
try {
int value = maybe;
System.out.println(value);
} catch (NullPointerException e) {
System.out.println("Cannot unbox null!");
}
}
}算術演算中のnull
この落とし穴は式の中でも発生します。nullのラッパーを加算すると、先にアンボクシングされるため、計算が実行される前に例外が発生します。
public class Main {
public static void main(String[] args) {
Integer count = null;
try {
int total = count + 5;
System.out.println(total);
} catch (NullPointerException e) {
System.out.println("Null in arithmetic!");
}
}
}nullへの対策
アンボクシングする前に、必ずラッパーがnullでないか確認するか、デフォルト値を指定してください。
public class Main {
public static void main(String[] args) {
Integer maybe = null;
int safe = (maybe != null) ? maybe : 0;
System.out.println(safe);
}
}==とキャッシュによる意外な動作
Integer.valueOfは-128から127までの値をキャッシュします。そのため、この範囲の2つのボックス化された値が同じオブジェクトを共有することがあり、==はtrueを返します。
public class Main {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
}
}キャッシュ範囲外
キャッシュ範囲を超えると、ボクシングのたびに別のオブジェクトが作成されます。この場合、数値が等しくても==は参照を比較するため、falseを返します。
public class Main {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
System.out.println(a == b);
}
}equalsを必ず使用
ラッパー型に対する==はオブジェクトの同一性を比較するため、実際の数値を比較するには.equals()を使用する必要があります。
public class Main {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
System.out.println(a.equals(b));
}
}プリミティブとの==の混在
==の片方がプリミティブの場合、Javaはラッパー型をアンボックスするため、値による比較になります。これは信頼できますが、ラッパー型がnullの場合は例外が発生する可能性があります。
public class Main {
public static void main(String[] args) {
Integer a = 200;
int b = 200;
System.out.println(a == b);
}
}ループ内に潜むボクシング
ループの累積変数をラッパー型として宣言すると、反復のたびに新しいオブジェクトが生成されます。次の例でlongの代わりにLongを使用すると、何度もボクシングが発生します。プリミティブ型を優先してください。
public class Main {
public static void main(String[] args) {
long sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i;
}
System.out.println(sum);
}
}Map.getはnullを返す
実際の開発でよくあるバグに、Map.getが存在しないキーに対してnullを返すことがあります。その結果をintにアンボックスすると例外が発生します。代わりにgetOrDefaultを使用してください。
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
int score = scores.getOrDefault("missing", 0);
System.out.println(score);
}
}安全に使用するために
オートボクシングによるバグの大半は、次の2つの習慣で防げます。nullの可能性がある値を決してアンボックスしないこと、そしてラッパー型の値は==ではなく必ず.equals()で比較することです。
理解度チェック
オートボクシングの落とし穴について、理解度を確認しましょう。
まとめ
オートボクシングの主な落とし穴について学びました。
nullのラッパー型をアンボックスするとNullPointerExceptionが発生する- nullチェックまたはデフォルト値で防ぐ
- ラッパー型に対する
==は参照を比較し、-128から127までの値はキャッシュされる - 値を比較するときは必ず
.equals()を使用する - マップ検索でnullを避けるには
getOrDefaultを使用する
よくある質問
「オートボクシングの落とし穴」レッスンは無料ですか?
はい。「オートボクシングの落とし穴」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「オートボクシングの落とし穴」で何を学びますか?
Nullのアンボクシングと==の落とし穴を学びます ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「オートボクシングの落とし穴」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- プリミティブ型とラッパー型
- オートボクシングとアンボクシング
- パースとvalueOf
- オートボクシングの落とし穴