私は匿名のサブクラスで遊んでいましたが、私が逃げることができない問題を発見しました。匿名サブクラス内のJava汎用オブジェクトの構築
EDIT:問題トーマスのおかげで解決され、完全な作業コードをペーストビン(Foo.java; FooTest.java)にある
2クラス。 fooとFooTest ... コード最初:
class Foo {
public Foo() {}
public void whichClassAmI() {
System.out.println(this.getClass());
}
public void say() {
System.out.println("Foo says: nothing");
}
public <T extends Foo> T getAnotherFoo() {
try {
Class<? extends Foo> c = this.getClass();
T r = (T)(c.getConstructor().newInstance());
return r;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
_
class FooTest {
public static String stuff = "";
public static void main (String[] args) {
Foo f1 = new Foo();
// instance of anon subclass
Foo f2 = new Foo(){
public void say() {
System.out.println("Modded Foo says: " + stuff);
}
};
f1.whichClassAmI();
f2.whichClassAmI();
stuff = "stuff";
f1.say();
f2.say();
Foo f3 = f1.getAnotherFoo();
f3.say();
Foo f4 = f2.getAnotherFoo(); // <-- exception here
}
}
ので、このコードは、危険な動作の警告でコンパイルが実行され、例外がスローされます。出力は次のとおりです。
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
class Foo
class FooTest$1
Foo says: nothing
Modded Foo says: stuff
Foo says: nothing
Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodException: FooTest$1.<init>()
at Foo.getAnotherFoo(Foo.java:20)
at FooTest.main(FooTest.java:23)
Caused by: java.lang.NoSuchMethodException: FooTest$1.<init>()
at java.lang.Class.getConstructor0(Class.java:2723)
at java.lang.Class.getConstructor(Class.java:1674)
at Foo.getAnotherFoo(Foo.java:17)
... 1 more
私は理解していないことである。
F2クラスがFooTest $ 1であり、このクラスには、(1)trueの場合はFoo
を延長しないことのようですFooTestで$ 1
(1)が偽で、(2)が正しく動作すると、なぜ "Class c = [...]"が設定できるのですか?
1へ
私が指摘したリンクを読んでいますしかし、私はこれを私のanonサブクラスに適応させる方法を理解していません。getDeclaredClasses doenstはどのクラスも返します(サブクラスを宣言していないので明白です)。また、私はあなたに "Foo。(Foo)"というjava.lang.NoSuchMethodException:Fooクラスのコンストラクタに外部インスタンスを取得しようとしたときの方法を変更しました。そのコンストラクタを作成すると、もう一度古い例外です。 –
cdx
@cdxよく、 'c.getConstructor(FooTest.class).newInstance(someFooTestInstance)'のようなものを試してください。これは 'FooTest $ 1'インスタンスを作成し、' FooTest'にアクセスする場合にのみ機能します。囲むクラスを取得するには 'getClass()。getEnclosingClass()'を実行してください。 – Thomas
@cdxコメントへのあなたの追加について:外側のクラスは 'Foo'(スーパークラス)ではなく' FooTest'です。 – Thomas