既知のタイプのクラスリテラルを作成する方法:クラス<リスト<文字列>>

StackOverflow https://stackoverflow.com/questions/2012306

  •  19-09-2019
  •  | 
  •  

質問

次のように乗ります:

public Class<List<String>> getObjectType() {
    // what can I return here?
}

どのようなクラスリテラル式Iは、ジェネリックを満足してコンパイルします。このメソッドから復帰することができますか? List.classはコンパイルされません、どちらもList.<String>classません。

あなたが迷っている場合は、

「なぜ」、私はFactoryBean<List<String>>を実装するために私を必要とSpringのClass<List<String>> getObjectType()の実装を書いています。しかし、これはのないの春の質問です。

編集の私の悲しげな叫びはSpringSourceので権力によって聞いてきた、そしてので春3.0.1はgetObjectType()の戻り値の型がきちんと問題を回避する、Class<?>に変更されます<。 / P>

役に立ちましたか?

解決

あなたは常に

このように、あなたが必要なものにキャストすることができます
return (Class<List<String>>) new ArrayList<String>().getClass();

または

return (Class<List<String>>) Collections.<String>emptyList().getClass();

しかし、私はそれはあなたが後にしているものではないのですと仮定します。まあそれは警告で、動作しますが、それはまさに「美しい」ではありません。

私はこれを見つけた。

  

なぜ、何のクラスでは、ワイルドカードパラメータ化された型のリテラルはありません?

     

ワイルドカードパラメータ化された型には、正確な実行時の型表現を持っていないので。

だから、行くための唯一の方法かもしれないキャスティングます。

他のヒント

あなたは、構築物Class<List<String>>を使用しないでください。それは無意味であり、Javaで警告を生成する必要があります(ただし、しません)。あなたはClass<List>を持つことができますので、クラスのインスタンスは常に、生の種類を表します。それでおしまい。あなたはList<String>のような具体化ジェネリック型を表すために何かをしたい場合はGuiceのは使用していますように、あなたは「スーパータイプのトークンを」必要があります。

ます。http://google-guice.googlecode。 COM / gitの/ javadocを/ COM /グーグル/注入/ TypeLiteral.htmlする

Class<List<String>>の存在は本質的に危険です。ここに理由です。

// This statement generates a warning - for a reason...
Class<List<String>> unsafeListClass = (Class<List<String>>) (Class<?>) List.class;

List<Integer> integerList = new ArrayList<Integer>(); // Ok
integerList.add(42); // Ok

System.out.println(unsafeListClass.isInstance(integerList)); // Prints "true".
List<String> stringList =
   unsafeListClass.cast(integerList); // Succeeds, with no warning!
stringList.add("Hello, World!"); // Also succeeds with no warning

for (int x: integerList) {
    // Compiles without warning, but throws ClassCastException at runtime
    System.out.println(100-x);
}

いくつかの洞察力を与えるspringframework.org上このリンクに見つかります。

例えばます。

List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();

あなたはこのようにそのメソッドを実装することができます:

public Class<List<String>> getObjectType() {
    return (Class<List<String>>) ((Class)List.class);
}

SUNのフォーラムでこの議論をチェックします:

http://forums.sun.com/thread.jspa?threadID=5253007

そして「スーパータイプトークン」を使って、周りの作業を説明し、参照のブログ記事:

http://gafter.blogspot.com/2006/12 /super-type-tokens.htmlする

私は、リテラル、任意のクラスがClass.forName(...)にコンパイルされ、これは、実行時に起こるので、残された一般的な情報がないので、これは、全く可能であるかはわからない。

私はわからないが、私は尋ねた、次の質問は...あなたに関連性があるかもしれません。

これらのタイプのJavaのジェネリック型パラメータと操作

これは何について:

public class TestMain {
    public static void main(String[] args) throws Exception {
        Type type = TestMain.class.getMethod("dummy").getGenericReturnType();
        System.out.println("type = " + type);
    }

    public List<Integer> dummy() {return null;}
}

この印刷物ます:

type = java.util.List<java.lang.Integer>

以下のアプローチには問題がある:

> public Class<List<String>> getModelType() {
>   return (Class<List<String>>) new ArrayList<String>().getClass();
> }

例えば。あなたは、オブジェクトのタイプが言うかどうかをテストしたい場合は、

org.eclipse.emf.common.util.BasicEList<String> 

型である

List<String> 

上述getModelType()アプローチの結果に基づいて、例えば

BasicEList<String> fromObject = ...;
if (getModelType().isAssignableFrom(fromObject.getClass())) {
    transferFromModelToUi(getModelType().cast(fromObject));
}

(getModelType()はList型としないのArrayListのクラスオブジェクトを返すため)両方のオブジェクトは、インタフェースリストを実装するので、それが真でなければならないのに対し、それは偽になります。

ここで私のために働いたアプローチは、(ビット面倒が、上記の例の結果を修正するためにつながり、静的イニシャライザに移動させることができる)である

public Class<List<String>> getModelType() {
    Class<?> arrayListClass = new ArrayList<String>().getClass();
    Class<?>[] interfaces = arrayListClass.getInterfaces();
    int index = 0;
    for (int i = 0; i < interfaces.length; i++) {
        if (interfaces[i].equals(List.class)) {
            index = i;
            break;
        }
    }
    return (Class<List<String>>) interfaces[index];
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top