Thing thing = new Thing();
のような文が新しいオブジェクトで結果は(thing
は、既存のオブジェクトを指して終わる可能性があること、すなわちどのような方法を)作成されなかったことを、Javaのいずれかの方法はありますか?
Thing thing = new Thing();
のような文が新しいオブジェクトで結果は(thing
は、既存のオブジェクトを指して終わる可能性があること、すなわちどのような方法を)作成されなかったことを、Javaのいずれかの方法はありますか?
new
オペレータは新しいヒープスペースを割り当て、コンストラクタを呼び出します。あなたは常に新しいオブジェクトをその方法で取得します(他の人が指摘するように、コンストラクタに例外がスローされない限り)。
可能であれば、内部プールからオブジェクトを再利用するInteger.valueOf()
のような、参照を返す静的メソッドでは少し違いがあります。
これは偉大なJoshua Blochの "Effective Java" –
Thingのコンストラクタが例外をスローすると、オブジェクトは作成されません。しかし、thing
は、Thingの別の既存のインスタンスを指しません。
でもヌル値でも推奨されるパターンです。 「Thing t = new Thing();」のようなコードを見るのは奇妙です。 if(t == null)... ' - それは起こりません –
いいえ、メモリに空きがない場合は、OutOfMemoryErrorを取得する必要があります。
もちろん、Thingコンストラクタによってスローされる他の例外が存在する可能性があります。
hmmm、なぜOutOfMemoryErrorではないのですか?ちょうど興味がある。 –
正しい例外は実際にOutOfMemoryErrorです。 – cd1
@ CD1 @Timミスを訂正しました。私はそれがそれのようなものであることを知っていた。私の悪い –
質問が正しく理解されているかどうかわかりません。
新しいオブジェクトの割り当てと初期化のための新しい定義はです。
オブジェクトに静的な参照を格納してから、新しいオブジェクトを作成するために複製することはできますが、そのオブジェクトはまだ新しいオブジェクトであると思います。
this
の値を変更することはできません(それ以外の場合は、コンストラクタでthis = oldObject
などと言うことができます)。これを行うには、前に説明したように例外をスローするしかありません。
私が知っている限り、それはoperator new
をオーバーロードするか、配置の新規または他のアロケータのものを行うことができるC++と似ていません。 (しかし、私はJLSに精通していません)
を使用すると、常に新しいオブジェクトが割り当てられて作成されます。しかし、の概念を参照しているかもしれません、オブジェクトとプールに格納され、スペースを節約するために再利用することができます。良い例として、JavaのString interningのこの記事を参照してください。
新しいものは常に新しいです(プリミティブラッパーには例外があります)が、オブジェクトを再利用することが望ましい動作である場合は、特定のデザインパターン(シングルトン、ファクトリ、プールなど)で行うことができます。
Javaでは、私が考えることができるのは、シングルトンパターンを使用することだけです。これは、Thingの複数の新しいインスタンスを作成するのではなく、毎回同じオブジェクトのインスタンスを作成します。
'new'を使うたびに、新しいインスタンスを作成しています。期間。シングルトンパターンでは、 'new SingletonClass()'ではなく 'SingletonClass.getInstance()'を呼び出しています。 –
コンストラクタが例外をスローすると、オブジェクトが作成されないという人がいます。私はこれが真実ではないことを指摘したいと思います。例として、この非常に悪いコードを見てみましょう:
public class Test {
static int count;
static Set<Test> set = new HashSet<Test>();
int id = count++;
public Test() {
set.add(this);
throw new RuntimeException();
}
public static void main(String[] args) throws Exception {
for(int i = 0; i < 5; i++) {
try {
new Test();
} catch(Exception e) {
}
}
System.out.println(set);
}
public String toString() {
return "Test[" + id + "]";
}
}
出力は次のようになります。
[Test[0], Test[1], Test[2], Test[4], Test[3]]
new
は、新しいオブジェクトを毎回作成されます。
newは常に新しいオブジェクトを作成します。 javaでは、newを使ってオブジェクトを再利用することはできません。実際には、これは特定のJavaクラスでパフォーマンスの問題につながります。例えば、 Booleanクラスは実質的に2つの値(trueまたはfalse)しか格納できませんが、ユーザーはnewを使用して同じ値を持つ複数のオブジェクトを作成できます。コードthing
の行を実行した後
号
は、その行の前に存在していたオブジェクトを参照することはありません。
クラスを初めて参照する場合、およびクラスが初期化に失敗した静的ブロックを持つ場合は、new
の呼び出しが失敗する可能性があります。静的なブロックまたはコンストラクタで発生する実行時エラーが発生すると、websphereアプリケーション・サーバー内での使用のコンテキストでClassNotFound Exceptionをスローする新しい呼び出しが発生する動作を経験しました。 Websphereクラス・ローダーは、ランタイム例外のために、クラスのロードを明らかに拒否します。
なぜお尋ねしますか?あなたはどこかで奇妙な行動をしていますか? –
奇妙な動作はありません。不思議なことに、私はInteger(int i)コンストラクタについて読んでいました。その目的は、静的メソッドInteger.valueOf(int i)が必要に応じてオブジェクトを再利用するので、より良いかもしれないという点でした。 、コンベンショナルな人が再利用のことをするために、慣習的ではない。 –
はい、不可能です。 C++では 'new'演算子をオーバーライドできますが、Javaでは実行できません。それは私を悲しくさせない。 –