2017-03-18 15 views
-1

讓我們考慮下面的代碼:Java中的getGenericSuperclass()。它是如何工作的?

package index; 

public class Main { 
    public static void main(String[] args) { 
     Inner inner = new Inner(); 
     Type t = inner.getClass().getGenericSuperclass(); 
     ParameterizedType p = (ParameterizedType) t; 
     Type[] a = p.getActualTypeArguments(); 
     try { 
      Custom c = (Custom) ((Class) a[0]).newInstance(); 
      c.f(); 
     } catch (Exception e){} 
    } 

    private static abstract class AbstractClass<T> { 
     public abstract void doSth(); 
    } 
    private static class Inner extends AbstractClass<Custom>{ 
     public void doSth() { 
     } 
    } 
    private static class Custom{ 
     public Custom(){ 

     } 
     public void f(){ 
      System.out.println("Custom"); 
     } 
    } 
} 
  1. 它的工作原理,我不明白它是如何做的工作。它表明可以獲取有關超類參數的信息。我不知道如何獲得這樣的信息,因爲我查看字節碼,並且沒有這樣的信息:

  2. 可以這樣做嗎?

+0

1.閱讀['Class.getGenericSuperclass()'](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getGenericSuperclass--)javadoc。是的。 –

+0

你顯示的是'Main',而不是'Inner'的字節碼,所以它不能告訴你,Inner是否存儲了它的通用超類。準確地說,這甚至不是字節碼,這是某個字節碼處理程序的輸出。如果該程序輸出缺少某些信息,則不能證明該信息在類文件中不存在。 – Holger

回答

1

.class文件中有Signature屬性,請參見JVMS §4.7.9

如果編譯Main.Inner與javap -verbose,你會發現這個屬性:

Signature: #14 // Lindex/Main$AbstractClass<Lindex/Main$Custom;>; 

Class.getGenericSuperclass執行提取與native method的幫助下這個屬性,然後分析,驗證並將其轉換爲Java表示。所以,獲取這些信息是絕對有可能的。

+0

謝謝! 「所以,這是絕對有可能的,並且** OK **以獲得這些信息。」但是,從軟件使用的角度來看,它可以嗎? – Gilgamesz

+0

@Gilgamesz我不確定你的意思是「軟件工程的意義」*,但是,有時候會使用這種技術。對「getGenericSuperclass」的調用是否合理,取決於特定的用例。 – apangin

相關問題