2013-07-05 216 views
4

得到所謂的類名我有這樣定義了兩個類:的Java:從靜態方法

class A { 
    public static String getName(){ 
     Class c = getCalledClass(); 
     return c.getSimpleName(); 
    } 
} 

class B extends A { 
    //no methods are defined here! 
} 

我想知道是否有可能構成static方法getCalledClass()這樣調用A.getName()將返回AB.getName()將返回B

謝謝。

+3

傳遞調用類作爲參數 – m0skit0

+0

更簡單,更快更簡單 - 當然,但是B.getName(B.class)不如B.getName()更直觀 - 如果沒有其他解決方案,這就是我將最終做.. – bennyl

+0

在什麼情況下被調用的類將會有所不同?就像如果你做B.getName()被調用的類是B,爲什麼我們需要傳遞這些數據? – MohamedSanaulla

回答

6

這是不可能的,至少不是您所要求的一般意義。

There is no method B.getName()。雖然你可以在代碼中輸入它,但它會被編譯成相同的字節碼到A.getName()(我想你也會得到編譯器的警告)。

因此,在運行時,沒有辦法知道某人如何引用靜態方法 - 就像無法告訴調用方使用的是什麼局部變量名稱一樣。

+0

測試編譯的代碼 - 你是對的..好吧,我想我將不得不請求類作爲參數.. 謝謝。 – bennyl

0

我不知道你是否可以按照你的要求去除靜電或不靜電。如果你可以刪除靜態並使用多態,那麼你可以得到你想要的。以下是我測試的代碼示例。

class A { 
    public String getName(){ 
     Class c = this.getCalledClass(); 
     return c.getSimpleName(); 
    } 

    Class getCalledClass() {   
     return A.class; 
    } 
} 

class B extends A { 
    Class getCalledClass() { 
     return B.class; 
    } 
} 

class TestApplication { 
    public static void main(String[] args) { 
     A objA = new A(); 
     System.out.println(objA.getName()); 

     A objB = new B(); 
     System.out.println(objB.getName()); 
    } 
} 
0

堆棧跟蹤將只包含該靜態方法定義的類的名稱。即使您撥打B.method(),您也會在堆棧跟蹤中看到A.method()。使用靜態方案你不能可靠地提取你想要的信息。

如果您使用非靜態方法,那麼this將是您正在尋找的類型的實例。

public String getName() { 
    return this.class.getSimpleName(); 
} 
0

當javac編譯器找到一個對B.getName()的調用時,它將它解析爲A.getName(),並在字節代碼中對A.getName()進行靜態調用。

java中沒有任何機制可以從字節碼中推導出源代碼中使用的表單。

如果您想將B.getName()設置爲與A.getName()不同的方法,您必須在B中定義一個名爲getName()的方法。由於在該方法中被調用的類將始終爲'B',因此不需要混淆堆棧跟蹤或其他機制。但是,一般來說,如果你認爲它在點之前很重要,那麼可能會有更好的面向對象設計供您使用。