ホームページ  >  記事  >  Java  >  Java の基本的な 4 つの質問、いくつ答えられますか?

Java の基本的な 4 つの質問、いくつ答えられますか?

伊谢尔伦
伊谢尔伦オリジナル
2016-12-05 13:08:511047ブラウズ

1. == 演算子の使用方法
まず、興味深いコードを見てみましょう
Integer c = 100,d=100; new Runnable() { public void run() { System.out.println(a==b); }
この質問が正しい答えを思いつき、その背後にある原理を理解できれば。つまり、基本は大丈夫ということです。あなたの答えが真実で真実であれば、あなたの基礎が欠けています。
最初に答えを発表し、コードを実行すると、 false true が返されます。 == は 2 つのオブジェクトの参照を比較することがわかります。ここでの abcd はすべて新しく作成されたオブジェクトであるため、論理的には false を入力する必要があります。この質問の興味深い点は、インタビューの質問であっても、フォーラムのディスカッション領域であっても、この質問の出現率が高いことです。原理は実際には非常に単純です。Integer.java クラスを見てみましょう。それが明らかになるでしょう。

public static Integer valueOf(int i) { return i >= 128 || i 整数 c = 100; を宣言するとき。このとき、自動ボックス化処理が行われます。簡単に言うと、基本データ型は Integer オブジェクトに変換されます。Integer オブジェクトへの変換は、ご覧のとおり、-128-127 というメソッドが呼び出されます。 Integer にキャッシュされます。公式の説明によると、小さい数値の方が頻繁に使用されるため、パフォーマンスを最適化するために、その間の数値がキャッシュされます。これが、この質問に対する答えが偽りであり、真実である理由です。宣言された Integer オブジェクトの値が -128 ~ 127 の場合、同じオブジェクトを参照するため、結果は true になります。

2. 次に、コードを見てみましょう
String s1 = “abc”;

String s3 = new String(s1 == s2) );

System.out.println(s1 == s3);
この質問の答えをもう一度当ててみましょう?
== の構文によれば、まず、s1、s2、s3 は 3 つの異なるオブジェクトです。一般的に、出力は false になります。ただし、プログラムの実行結果は実際には true または false です。 false の 2 番目の出力は理解できますが、true の最初の出力は不可解です。いくつかの基本的なタイプの変数とオブジェクト参照変数は関数のスタック メモリに割り当てられ、新しいオブジェクトと配列はヒープ メモリに格納されることがわかっています。ただし、これとは別に、コンスタントプールと呼ばれるエリアがあります。
通常 String s1 = “abc”; と考えるのと同じように、このように宣言された文字列オブジェクトの値は定数プールに格納されます。 String s1 = "abc" のようなオブジェクトを作成すると、"abc" は定数プール (文字列プールとも呼ばれます) に格納されます。 String s2 = "abc" への参照を作成すると、Java の最下層で次のことが行われます。 「abc」が定数プールに存在するかどうかを確認します。存在する場合は、s2 がこの値を指すようにし、定数プールに存在しない場合は作成され、プールに追加されます。 。だからこそ、答えには真と偽があるのです。


3. 最後のキーワード
コードを見てみましょう
public void mRun(final String name){ new Runnable() { public void run() { try { Thread.sleep(1000) } catch (InterruptedException e ) { // TODO 自動生成された catch ブロック e.printStackTrace(); } System.out.println(name) } }.start();
このようなコードをたくさん書いたことがあると思います。内部クラスはローカル変数にアクセスします。 場合によっては、ローカル変数の前に Final 修飾子を追加する必要があります。追加しないと、コンパイラによってエラーが報告されます。通常、これが私たちが行うことです。さて、ここで 2 番目の質問が来ます。なぜ、final 修飾子を追加する必要があるのでしょうか?ほとんどの友人はこの問題について一度も考えたことがなく、それを使用するときはただ追加するだけで、原則を深く掘り下げたことはないと思います。これは優れたプログラマにとっては望ましいことではありません。何が起こっているのかだけでなく、その理由も理解する必要があります。

それでは、最後のキーワードを追加する必要がある理由を分析しましょう。まず、内部クラスのライフサイクルはメンバー レベルですが、ローカル変数のライフサイクルは実際にはメソッド本体などで行われます。つまり、mRun メソッドが実行され、新しいスレッドが実行されているときに、新しいスレッドが 1 秒間スリープする状況が発生します。メインスレッドは実行を継続し、mRun が実行され、name 属性のライフサイクルが終了します。

1秒後、syetem.out.printh(name)が実行されます。ただし、この時点では、名前の有効期限が切れており、メモリには存在しません。この種のエラーを防ぐために、Java では内部クラスのローカル変数を Final キーワードで変更する必要があることを厳密に要求しています。ローカル変数が Final によって変更された後、ローカル変数のコピーがメモリ内に保持され、内部クラスがそれにアクセスするとき、実際にアクセスされるのはこのコピーです。これは、ローカル変数のライフサイクルを延長するようなものです。結局のところ、Java エンジニアが事前にこの穴を埋めてくれました。そうでなければ、内部クラスのローカル変数について心配する友人がどれだけいるかわかりません。


4. Integer と int について
Integer a = new Integer(1000);
Integer c = new Integer(10); ;
System.out.println(a == b);
System.out.println(c == d);
この質問に対する答えがすぐに得られる場合。 , おめでとうございます。== をより完全に理解できました。
——————————————————分割線———————————————————————— –
正解: true、false
この回答を見た後、多くの友人が混乱するでしょう。最初の質問によると、整数は -128-127 をキャッシュしませんか。これは true であるはずではありませんが、よく見てみると、ここでの Integer は新しいものであり、キャッシュされていないため、結果は false になっています。
それでは、なぜ最初のものが正しいのかをもう一度見てみましょう? まず第一に、ここでの値は 1000 ですが、これは私たちが知っている整数キャッシュとはまったく関係がありません。これはキャッシュとは関係がなく、 a は新しく作成されたオブジェクトであるため、入力が false になるのは当然です。ただし、ここでの b は int 型であることに注意してください。 int と Integer が == 比較されると、Java は自動的に Integer をアンボックス化します。つまり、Integer を int 型に変換します。そのため、ここでは int 型の値が比較されるため、結果は true になります。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。