Javaでオブジェクト(または何か)を作成するとき、たとえば、次のことの違いは何ですか
Dog d = new Dog();
する代わりに
Dog d;
その後、(メソッドの内部およびメソッドの先頭で)終了します
d = new Dog();
最初のものはもっとシンプルで簡単ではないでしょうか? なぜ人々は2番目の方法でそれを行うのですか?
次のシナリオを考えてください。のコンストラクタがDog例外をスローできると仮定します。
try {
Dog d = new Dog();
} catch(Exception ex) {
// treat exception
}
d.bark();
ブロックdの外側には表示されないため、これはコンパイルされません。tryあなたがする必要があるのはこれです:
Dog d = null;
try {
d = new Dog();
} catch(Exception ex) {
// treat exception
}
if(d != null) d.bark();
そして、このような他の多くの状況があります。たとえば、dある条件に基づいて異なる方法で初期化されるif-elseブロックがあるとします。
Dog d = null;
if(/* condition */)
d = new Dog("Lassie");
} else {
d = new Dog("Sam");
}
d.bark();
この質問には、いくつかの重要な文脈が欠けています。変数の定義と使用が別のスコープにある場合、実質的な違いがあります。例えば:
class A {
Dog d;
void foo() { d = new Dog(); }
}
... のすべてのメンバーが Dog にアクセスできるようにしますclass A。
用途が同じ範囲内であれば、
class A {
void foo() {
Dog d;
d = new Dog();
}
}
...コードは1行または2行で同じように実行されるため、可読性の問題です。
多くの理由。理由の 1 つは、初期化が実行時に決定される条件に依存することです。例えば、
Animal pet;
...
if(input == 0) pet = new Dog();
else pet = new Cat();
...
pet.sleep();
これは参照の宣言のみです(あなたdは type を持つと言いますDog):
Dog d;
これは新しいオブジェクトを作成し、それを参照変数に割り当てdています:
new Dog();
両方を行うことが多いため、組み合わせることができますが、常にではありません。
宣言と初期化を習慣的に分離することはお勧めできませんが、
これを行う必要がある状況がいくつかあります(try catch の例を参照)。
コードの可読性が向上する状況がいくつかあります (Max Schmidt の例を参照)。
コードをより堅牢にする状況がいくつかあります。
最後の点を説明するために、変更された Max Schmidt の例を考えてみましょう。
Dog d = null;
if (input.equals("lab")) {
d = new Labrador();
} else if (input.equals("bull")) {
d = new Bulldog();
}
d.walk();
バグが見えますか?inputも も もでない"lab"場合、コードは犬"bull"の散歩で死んでしまいます。null
ただし、 の初期化を削除するとd、コンパイラは、初期化されていないコードを通るパスがあることを通知しますd。注意を払っていれば、コードを実行する前にバグを見つけて修正します。
オブジェクトを宣言するときに、オブジェクトを構築する方法を常に知っているとは限らないためです。例えば:
Dog dog;
if ("M".equals(sex)) {
dog = new Dog("Medor");
}
else {
dog = new Dog("Mirza");
}
dog.walk();
これは、怠惰な初期化の大まかな例です。プログラムでは、Dogオブジェクトの実際のインスタンスが必要になることはない可能性があります。そのような場合は、Dog参照を宣言するだけで、メモリをあまり消費せず、後で必要に応じて初期化できます。
オブジェクトの作成とオブジェクトの宣言。あなたはそれについてここで読むことができます
を実行すると、型Dog d = new Dog();の変数を宣言し、演算子を使用して変数を作成します。dDognew
したがって、通常は最初に必要な変数を宣言し、実際に使用される場合にのみ作成します。
理由はありません、それは単に貧弱なコーディング慣行です。初期化する前に使用することはできないためd、先に宣言しても意味がありません。
Dog d;
//...you cannot use `d` in any way! It won't compile
d = new Dog();
//now you can
ただし、これは次のとおりです。
Dog d = null;
//...
d = new Dog();
誰かがチェックするかもしれないので意味がありnullます(怠惰な初期化など)
簡単にするために、実際には次のことをお勧めします。
final Dog d = new Dog();
2つ目は、Dogが作成されるtry / catchのようなものがある場合に、より役立つ可能性があります。dogインスタンスを作成しても、そのメソッドの他のロジックが停止することはありません。try / catchの後に使用したいdogインスタンスがある場合は、それ以外の場合はロジックを続行します。
try / catch内で最初の構文を使用する場合、それを外部で使用することはできません。
try {
Dog d = new Dog();
} catch(Exception ex) {
}
d.methodCall();
たとえば、犬がラブラドールとブルドッグのスーパークラスである場合は、2 番目の方法以外に方法がない場合があります。
Dog d;
if (input == "lab"){
d = new Labrador();
}else if {
d = new Bulldog();
}
d.urinate():