を利用できませんtryブロックマスーパー()を呼び出?
質問
なので、Javaでは、最初の行のコンストラクタを呼び出すスーパー...での暗黙的な呼び出しスーパー()、または明示的に呼び出しの別のコンストラクタです。私が知りたいのは、なぜすることはできないのでしょうかけるには、tryブロックの周り。
私の特定の場合は、模擬授業のためのテストです。ありませんのデフォルトのコンストラクタかもしれないけど、私は一つの試験を簡単になります。また、ラップ、スローされる例外のコンストラクタへのRuntimeException.
では、どうしたいのです:
public class MyClassMock extends MyClass {
public MyClassMock() {
try {
super(0);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Mocked methods
}
がJavaと文句をスーパーなのです。
私の回避策:
public class MyClassMock extends MyClass {
public static MyClassMock construct() {
try {
return new MyClassMock();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public MyClassMock() throws Exception {
super(0);
}
// Mocked methods
}
この回避策?なぜなJavaとさせて頂いていのですか?
いて、"なぜ"はJavaいただいて構築のオブジェクトを潜在的に矛盾した状態...しかし、やって模擬んのケアについての質問です。みとしっかりとした作りで、長きに上---少なくとも知っているのは私の例---たいていので?
I amをオーバー他の方法を使っていからのクラスはありませんリスクを私が使用していること初期化されていない変数です。
解決
残念ながら、コンパイラでコンパイルできな論理の原則のものはご存知の通りである安全でお場合、許したものの、こうして安心して出力します。
つまり、コンパイラな停止だけですので、停止皆様をはじめ、すべての人が知らないので安全でなく、ニーズに特別なります。があると思われその他の理由として、すべての言語は通常方法 安全でない ものばかります。
クライアントまで、フルのC#.当期純な規定は、唯一の方法を宣言するコンストラクタを呼び出ベースのコンストラクタはこの:
public ClassName(...) : base(...)
その際、ベースのコンストラクタが呼び出される前に呼び出され、身体のコンストラクタは、大きさを変えることはできません。
他のヒント
この行いを防ぐために新規作成 SecurityManager
オブジェクトから信頼できない。
public class Evil : SecurityManager {
Evil()
{
try {
super();
} catch { Throwable t }
{
}
}
}
そうすることを義務付けられているが、気に入ったので、あなたはそれに回答しました。恐らく私の理解しかできないに貢献する議論をまとめ、将来の読者の興味深い質問です。
という例のなオブジェクト。
もうクラスを定義するようなこと:
class A {
private String a = "A";
public A() throws Exception {
throw new Exception();
}
}
今が一致していると仮定すると、を作りたいと思ってい型のオブジェクトA try...catch
ブロックです。
A a = null;
try{
a = new A();
}catch(Exception e) {
//...
}
System.out.println(a);
明らかにし、出力このコード: null
.
なぜJavaせの一部を構版 A
?その点、コンストラクタに失敗した場合、オブジェクトの name
分野がすでに初期化されていですよね?
でも、Javaかを返し部分的に構築版 A
このオブジェクトが再度お試しください。のオブジェクトは矛盾した状態で排出されるJava.お値を説明変数ではないでも初期化され、保としてnullになります。
現在、ご存知のとおり、完全に新しいオブジェクト、そのすべてのスーパーの授業は初期化されます。る場合にはスーパー授業が行うと大きく異なる結果となる可能状態のオブジェクト?ことは不可能で決定する。
この精緻例
class A {
private final int a;
public A() throws Exception {
a = 10;
}
}
class B extends A {
private final int b;
public B() throws Exception {
methodThatThrowsException();
b = 20;
}
}
class C extends B {
public C() throws Exception { super(); }
}
きのコンストラクタ C
起動しているときに例外が発生した場合の初期化 B
, この値を最終 int
変数 b
?
など、オブジェクトC作成することはできませんので、偽のゴミではない完全に初期化されます。
私にとって、この理由を説明しコードすることは違法です。
思考をより深く理解Javaの内部での私の理解と、コンパイラのニーズのインスタンスを生成する導出クラスではそのベース(およびそのベースの前に(...))として打の拡張子をサブクラス.
ではないもの危険uninited変数である。きのうのサブクラス'コンストラクタ 前 基底クラス' コンストラクタ, は、基本的に求めのコンパイラの拡張ベースオブジェクトインスタンスが存在しない。
編集:お場合、 MyClass となりのベースオブジェクト、 MyClassMock はサブクラス.
わからないのJavaの実施社内での場合はコンストラクタのスーパークラスが例外をスローし、その目指すは世界中に存在するクラスのインスタンスだ。そんなことでは toString()
または equals()
方法は、例えば、彼ら継承されています。
Javaなどを可能にする側面があtry/catch周辺にはスーパー()を呼び出しのコンストラクタの場合1.きのオーバーライドすべてのメソッドからスーパークラス、2.使わないのです。XXX()条項がすべての音声にはあまりに複雑すぎる。
この問いには多くの回答がしたいと思っていっtidbitなぜこせない、具体的には答えによらなぜJavaできませんよろしくお願いします。なのでもう好きにしちゃってください...
今意してください super()
する呼び出される前に呼び出されば、サブクラスのコンストラクタでかった場合には、代わりに使用 try
や catch
ブロックの周り super()
のブロックというようなものです:
try {
super();
...
} catch (Exception e) {
super(); //This line will throw the same error...
...
}
場合にスーパー()fails in the
試block, it HAS to be executed first in the
漁block, so that
スーパーruns before anything in your subclass
sコンストラクタです。このようにまと同じような問題だったのが始:場合、例外がスローされますので、なにより運営されます。(この場合ですがスローされ再びcatchブロックです。)
現在、上記のコードがないことを許されるJava。このコード実行の半分のスーパーを呼び出し、呼び出して、でも、問題のある一部のスーパー。
現在、その理由とJavaない例外がスローされ 代わりに の呼び出し super()
では、例外が引っ掛けたり、強く引っ張ったかのプログラムに継続する な呼び出し super()
おサブクラスのオブジェクト なので例外がおオブジェクトとしてパラメータを変更してみてください価値を継承したインスタンス変数といって初期化されます。
一つの方法でを呼び出すことによって民間の静的な機能です。のtry-catchできる機能です。
public class Test {
public Test() {
this(Test.getObjectThatMightThrowException());
}
public Test(Object o) {
//...
}
private static final Object getObjectThatMightThrowException() {
try {
return new ObjectThatMightThrowAnException();
} catch(RuntimeException rtx) {
throw new RuntimeException("It threw an exception!!!", rtx);
}
}
}