簡體   English   中英

匿名子類中的Java通用對象構造

[英]java generic object construction within an anonymous subclass

我在玩匿名子類,發現一個無法解決的問題。

編輯:由於托馬斯 ,問題得以解決,完整的工作代碼在pastebin( 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

我不明白的是:

  1. f2類是FooTest $ 1,此類似乎沒有擴展Foo

  2. 如果(1)是true,為什么可以使用FooTest $ 1設置“ Class c = [...]”

  3. 如果(1)為假而(2)正確工作,為什么找不到方法?

到1): f2的類型為FooTest$1 ,它擴展了Foo ,但未打印出來,您僅獲得當前類,並且沒有超類或接口。

至2):由於1)為假,因此這里沒有問題:)

到3):問題在於匿名內部類FooTest$1需要創建一個外部FooTest實例。 通過反射調用構造函數將嘗試在包含FooTest的封閉實例的情況創建新實例,並且此類方法不可用(即,在沒有封閉類的實例的情況下創建內部類的實例的方法)。

您需要做的是獲取將封閉類的實例作為其參數的構造函數。 有關更多信息,請查看以下問題: 是否可以使用Java Reflection創建嵌套類的實例?

編輯

我再次閱讀您的代碼,感到FooTest$1愧,我錯過了這一點: FooTest$1類實際上是一個靜態內部類,因為它是在靜態main方法中創建的。 因此,它沒有構造函數接受封閉的類實例。

但是,由於您創建了類及其內聯的構造函數,因此該構造函數不是公開可見的。 因此, getClass().getConstructor()不會返回它(此類只會返回公共構造函數。在這種情況下,您必須使用getClass().getDeclaredConstructor() 。對於字段和方法也是如此,僅用於記錄) 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM