2011-12-21 32 views
2

実行時に参照のコンパイル時の型を取得する方法はありますか?実行時にコンパイル時のタイプ

例:

private void doSomething(final Object o) 
{ 
    // do somthing 
} 

final Number n = 1; 
doSomething(n); 

final Object o = 1; 
doSomething(o); 

final Integer i = 1; 
doSomething(i); 

第一コール - >数値

第二コール - >オブジェクト

第三コール - >整数

編集:これは非常に単純化しています問題のバージョン。私がやろうとしているのは、渡されるオブジェクトに関するフレームワークのメタデータの中で(言われているのではなく)検出することです。何が起こるかは、メソッドが最初にNumberで宣言されたIntegerとDoubleで呼び出されることです。

+1

'getClass()'?おそらく、APIをチェックアウトしてください。 –

+1

@Dave NewtonはNumberではない整数を返します。 – Stefan

+2

これはできません。 – SLaks

答えて

2

を確認するために私が見る唯一の方法は、オーバーロードを使用することです。しかし、継承関係の各クラスに対して、サブクラスを除外するためのオーバーレイ方法を指定する必要があります。

private void doSomething(final Object o) 
{ 
    // do something 
} 

private void doSomething(final Number n) 
{ 
    // do something 
} 

private void doSomething(final Integer i) 
{ 
    // do something 
} 

final Number n = 1; 
doSomething(n); // doSomething(final Number) is called. 
+0

私はオーバーロードを使用しなければならないのではないかと恐れていましたが、タイプを制限してコードを生成できる可能性があります。 – Stefan

+0

これは結局それほど悪くないかもしれません。私は、サポートされているデータ型用のインタフェースを作成し、次にそれにメタデータ処理コードを入れるためにプロキシ/ハンドラを使用することができました。クライアントは独自のインターフェースを作成することもでき、InvocationHandlerも引き続き動作します。 – Stefan

1

まったく簡単にはできません。

あなたはすでに関数の引数(Object)のコンパイル時を知っており、渡されたオブジェクトの実行時の型を(getClass()を使って)見つけることができます。しかし、あなたが求めている情報を得る方法はありません。

0

利用object.getClass()

private static void doSomething(final Object o) { 
    System.out.println(o.getClass().getSuperclass()); 
} 

private static <T extends Number> void doSomething(final T o) { 
    System.out.println(o.getClass()); 
} 


final Integer n = 2; 
doSomething(n); 

final Double n = 2D; 
doSomething(n); 
+0

これは、整数ではなく数を返します。 – Stefan

+0

@Stefan、私の答えを参照してください - 'Number'は抽象クラスであるため、' Number'のインスタンスを持つことはできません。 – Paul

+0

@Paul私の編集を参照してください – Stefan

0
あなたは 'instanceofの'

public class Test { 
    private static void doSomething(final Object o){ 
    if(o instanceof Number){ 
     System.out.println("it's a number!"); 
    } 
    System.out.println("canonical class : "+o.getClass().getCanonicalName()); 
    } 
    public static void main(String[] args) { 
    Number n = new Integer(10); 
    doSomething(n); 
    } 
} 

プリントアウト

it's a number! 
canonical class : java.lang.Integer 

Anothを使用することができます

えーオプションは、再帰的にスーパー

public class Test { 
    private static Class<?> doSomething(final Object o){ 
    // assuming o is not null 
    Class<?> klass = getSuperClass(o.getClass()); 
    return klass; 
    } 

    private static Class<?> getSuperClass(Class<?> klass){ 
    // if super class is object or null break recursion 
    if(klass.getSuperclass() == null || klass.getSuperclass().equals(Object.class)){ 
     return klass; 
    } 
    // keep looking higher up 
    return getSuperClass(klass.getSuperclass()); 
    } 

    public static void main(String[] args) { 
    Number n = new Integer(10); 
    System.out.println("n is a "+doSomething(n).getCanonicalName()); 
    Object o = new Integer(10); 
    System.out.println("o is a "+doSomething(o).getCanonicalName()); 
    Number d = new Double(10.0d); 
    System.out.println("d is a "+doSomething(d).getCanonicalName()); 
    String s = "10"; 
    System.out.println("s is a "+doSomething(s).getCanonicalName()); 
    Object so = "10"; 
    System.out.println("so is a "+doSomething(so).getCanonicalName()); 
    } 
} 

プリントアウト

n is a java.lang.Number 
o is a java.lang.Number 
d is a java.lang.Number 
s is a java.lang.String 
so is a java.lang.String 
+0

編集を参照してください。どのオブジェクトが渡されているのかわかりません。コンパイル時のタイプを「検出」しようとしています。 – Stefan

+0

その場合、メソッドのオーバーロードをお勧めし、どのメソッドが実際に呼び出されたかを確認します。 –

+0

私は過負荷を試すつもりです。 – Stefan

0

できません。 Numberは抽象クラスであり、抽象クラスのインスタンスを持つことはできず、オートボクシングを使用してプリミティブintを変換しているため、Integerは正解です。

+0

抽象的であれば問題ありません。実際にNumberであるコンパイル時の型を取得しようとしています。編集を参照してください。 – Stefan

+0

インスタンスは作成できませんが、参照は作成できます。それは〜のすべてです。 –

+0

@DaveNewton、インスタンスは参照です。 Javaでは、インスタンスを別のメソッドに渡すことは、参照を渡すことです(値渡し)。 – Paul

関連する問題