私は自分のJavaを試験の準備のために勉強していただけで、初期化されていないint/Integer値で一種の問題に遭遇しました。
class A
{
int x;
Integer y;
static int z;
static Integer z2;
public A(){}
}
クラスAのオブジェクトを初期化するとします。Aa = new A();
私はコンパイラでこれを試し、結果を得ました
a.x == 0; true
a.x == null; Static Error: Bad type in comparison expression
a.y == 0; Java.lang.NullPointerException
a.y == null; true
a.z == 0; true
a.z == null; Static Error: Bad type in comparison expression
a.z2 == 0; NullPointerException
a.z2 == null; true
さらに、相互作用ペインでさらに初期化されていないint/Interger比較をいくつか試して、x、yが上記のようにクラスインスタンス変数でない場合に異なる結果が得られるかどうかを確認しました。
int x;
Integer y;
x == 0; true
x == null; Static Error: Bad type in comparison expression
y == 0; Java.lang.NullPointerException
y == null; true
しかし、私の教授は講義で、値は次のようになるべきだと主張しています:
x == 0; Uninitialized
x == null; Undefined
y == 0; Java.lang.NullPointerException
y == null; Uninitialized
今、私は試験を書いている人を疑いたくありませんが、x == 0とy == nullの真理値は正しいですか?理由を教えていただければ幸いです。ありがとうございます。
a.x == 0
-a.xのデフォルト値は0であるため、true。a.x == null
-前述のとおり、これはコンパイル時のエラーです。これは §15.21. から続きます: "キャスト変換(§5.5)によっていずれかのオペランドの型を他方の型に変換することが不可能である場合、コンパイル時エラーが発生します。" null型は数値に変換できません。a.y == 0
-これはnullであるa.y,
を開梱しようとするため、NullPointerExceptionをスローします。上記とは異なり(リテラルnullがあります)、コンパイラーはa.y
がnullになることをコンパイル時に理解しようとしません。a.y == null
-a.y
がnullに初期化されているため、繰り返しになりますa.z == 0
-a.x
と同じ(静的を除く)a.z == null
-a.x
と同じ(静的を除く)a.z2 == 0
-a.y
と同じ(静的を除く)a.z2 == null
-a.y
と同じ(静的を除く)インタラクションペインの問題は、IDE実装方法次第です。xとyがローカル(初期化されていない)変数の場合、最後の4つの比較はすべてコンパイルに失敗します。
Int/longなどの単純型のJava値はnullにできないため、0で初期化されます。
Javaでは、クラス(静的)変数、インスタンス変数(例ではこれら)、および配列コンポーネントにデフォルト値が与えられます。一方、ローカル変数には明示的に値を指定する必要があり、デフォルト値を取得しません。
詳細は §4.12.5 を参照してください。
int x;
Integer y;
x == 0; true. because x is initialized to 0 by JVM
x == null; Static Error: Bad type in comparison expression
y == 0; Java.lang.NullPointerException
y == null; true, because y is uninitialized
class A
{
int x;
Integer y;
static int z;
static Integer z2;
public A(){}
}
あなたのコンパイラは言う
x == 0; true;
x == null; Static Error: Bad type in comparison expression
y == 0; Java.lang.NullPointerException
y == null; true
あなたの先生は言う
x == 0; Uninitialized
x == null; Undefined
y == 0; Java.lang.NullPointerException
y == null; Uninitialized
教師が異なる用語を使用していることを除いて、どちらも正しいです。その理由は、デフォルトでJavaオブジェクトの初期化されていない値を0またはnullに初期化します。教師はそれらを初期化されていないものとして参照します。これらの値はまだ初期化されていないため、彼は正しいです(ただし、まだデフォルト値)先生は、変数を常に初期化することをお勧めします。
編集:初期化されていないローカル変数は使用できません。
地元のほかに:
ユニット化されたintは0です。
ユニット化された整数はnullに等しい。
整数はオブジェクトです。一元化されたオブジェクトはnullと等しくなります。
intはプリミティブ型です。言語仕様では、初期化されていない値は0であると定義されています。
説明と動作に少し一貫性がないように見えるので、これは以前私を悩ませました。 言語仕様 の セクション4.12.5 を見ると、これについて説明し、コンパイラの動作を観察したことでうまくいくセクションがあります。
これが時々混乱していると思う理由は、私がSunから読んだ他の出版物( "Core Java 2"など)が、教授が示した動作を説明しているためです。別のバリエーションでは、初期化されていないプリミティブの使用を許可するが、初期化されていないオブジェクトの使用にフラグを立てるNetBeansを使用します;それがコンパイラであるかIDE選択であるかどうかはわかりません。
[編集:投稿の1つを確認した後、この混乱は、ローカル変数とフィールドの異なる動作に起因していると思います。]
クラス内のすべてのオブジェクト/変数は、オブジェクトがインスタンス化されるときにデフォルト値に初期化されます。
そのため、クラス内の変数には次の値があります。
int x = 0 //default value (value type)
Integer y = null //default values of any object; here Integer is reference type
...そして残りは同様に続きます。私の答えがお役に立てば幸いです!!!
この質問はしばらく前に出されたもので、正解はありますが、多少拡張できると思います。
公式チュートリアルページから数行引用します。 https://docs.Oracle.com/javase/tutorial/Java/nutsandbolts/datatypes.html
宣言されているが初期化されていないフィールドは、コンパイラによって適切なデフォルトに設定されます
ローカル変数は少し異なります。コンパイラーは、初期化されていないローカル変数にデフォルト値を割り当てません。初期化されていないローカル変数にアクセスすると、コンパイルエラーが発生します。
Javaプリミティブには数値の値があります。(それほど単純ではないので、詳細を読むことをお勧めします。)オブジェクトの値は、ある場所からの参照ですオブジェクトのコンテンツを見つけることができます。
プリミティブのデフォルト値は基本的に0ですが、オブジェクトのデフォルト値はnullです。 (初期化されていない場合とフィールドの場合)
あなたの例では、「0から0、nullからnull、nullから0」を比較しようとしています。
事実:null!= 0。
参考までに:この質問はすでにMatthew Flaschenによって見事に回答されていると思います。興味がある人のために情報を追加したかっただけです。