2017-03-18 10 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を読んでください。 2.はい。 –

+0

あなたが示したのは、 'Inner'ではなく' Main'のバイトコードなので、Innerが汎用スーパークラスを格納しているかどうかは分かりません。正確に言うと、これはバイトコードでさえありません。これは特定のバイトコード処理プログラムの出力です。そのプログラム出力に特定の情報がない場合、この情報がクラスファイルに存在しないことは証明されません。 – Holger

答えて

1

.classファイルにはSignatureという属性があります。JVMS §4.7.9を参照してください。

あなたはjavap -verboseでMain.Innerをコンパイルする場合は、この属性を見つけることができます:

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

Class.getGenericSuperclass実装はnative methodの助けを借りて、この属性を抽出し、解析し、検証し、Java表現に変換します。したがって、この情報を得ることは絶対に可能であり、OKです。

+0

ありがとう! "だから、この情報を得ることは絶対に可能で** OK **です。"しかし、ソフトウェアエンゲージメントという意味では大丈夫ですか? – Gilgamesz

+0

@Gilgamesz「ソフトウェア工学のセンス」*が何を意味するのか分かりませんが、このテクニックは時々使用されます。 'getGenericSuperclass'への呼び出しが正当化されるかどうかは、特定のユースケースに依存します。 – apangin

関連する問題