7

このような一般的なメソッド呼び出しを理解するのに問題があります:

object = ObjectGenerator.<T> getObject(objectName);

上記の状況のコンテキストは次のとおりです。

class GenClass<T> {

   private T object;

   // ... some code

   public void initObject(String objectName) {
      object = ObjectGenerator.<T> getObject(objectName);
   }
}

class ObjectGenerator {

   public static <T extends Object> T getObject(String name) {
      // some code
      return someObject;
   }
}

問題は、呼び出しの<T>前にどのような役割を果たすかです。getObject(objectName)

4

5 に答える 5

7

注:指定した特定の例では、正常にObjectGenerator.getObject(objectName);コンパイルされるはずです。

状況によっては、型推論メカニズムが次の事実を解決できない場合があります。

T object;
object = ObjectGenerator.getObject(objectName);

返されるタイプはT。このような場合、期待する戻り型を明示的に示すことにより、コンパイラーに少し助けを与える必要があります。

ジェネリック型を明示的に指定する必要がある不自然な例を次に示します。

class Example {
    public static <T> List<T> m1() {
        return m2(Arrays.<T> asList()); //Arrays.asList() would not compile
    }
    public static <T> List<T> m2(List<T> l) {
        return l;
    }
}
于 2013-02-12T18:24:12.860 に答える
0

私はここで何かを見つけました: https://stackoverflow.com/a/338906/443427それはあなたを助けるかもしれません。

私が読んだものから、コンパイラが再調整された値型を計算するために使用しなければならないジェネリックを表し、ジェネリックを転送することができます

注意として、これも正常に機能します(ObjectGeneratorがTと異なることを確認してください)。

public class ObjectGenerator<X> {
    public static <T extends Object> Set<T> getObject(String name) {
    // some code
    return null;
    }
}
于 2013-02-12T18:33:11.080 に答える
0

objectT の子になることができます。

もちろん、次のgetObjectように定義したほうがよいでしょう:

public static <T> T getObject(Class<T> objectClass, String name) {
   return objectClass.getConstructor(String.class).newInstance(name);
   //return objectClass.getConstructor().newInstance();
}

そうしないと、いわゆる型消去が発生するため、型安全な構築はできません。

于 2013-02-12T18:22:11.100 に答える
0

私は、受け入れられた答えに完全には同意しません。

このような場合、期待する戻り値の型を明示的に示すことで、コンパイラに少し助けを与える必要があります。

これは私には正しく聞こえません。ジェネリック メソッドと型の推論について理解しているので、角かっこで囲まれた型は、ジェネリック メソッドの戻り値の型を直接示しているわけではありません。むしろ、型Tは、戻り値の型、引数の型、ジェネリック メソッドに関連付けられたローカル変数の型である可能性があります。

実際、型推論メカニズムのおかげでT、ほとんどの場合 (特定の状況に限らず) 型パラメーターを指定する必要はありません。あなたの例では、他のほとんどの場合と同様に<T>、メソッド呼び出しから安全に省略できます。ObjectGenerator.<T> getObject(objectName)これは、ジェネリック メソッドの型が、結果が代入される、または返される型Tから容易に推測できるためです。つまり、メソッド呼び出しの前に宣言するので、型は として正常に推論されます。private T objectTT

私の主張は、決定的なチュートリアルからの次のステートメントによってバックアップできます。

型推論は、各メソッド呼び出しと対応する宣言を調べて、呼び出しを適用可能にする型引数 (または複数の引数) を決定する Java コンパイラの機能です。推論アルゴリズムは、引数の型を決定し、可能な場合は、結果が割り当てられる、または返される型を決定します。最後に、推論アルゴリズムは、すべての引数で機能する最も具体的な型を見つけようとします。

推論の仕組みに関する 2 つの例:

static <T> T pick(T a1, T a2) { return a2; }
Serializable s = pick("d", new ArrayList<String>());

型は、宣言された担当者の型に基づいてT推論されます。Serializable

public static <U> void addBox(U u, java.util.List<Box<U>> boxes) {}
BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);

型は、渡された引数の型に基づいてU推論されます (つまり、 type です)。したがって、上記のメソッド呼び出しから安全に省略できます。IntegerInteger.valueOf(10)Integer<Integer>

要約すると、ジェネリック メソッドの型パラメーターをその引数の型、または (メソッドの呼び出し時に) 結果が代入または返される型から推測できない場合を除き、メソッドの直前の型指定を安全に省略できます。呼び出し。

于 2013-02-12T19:47:20.853 に答える
-1
 object = ObjectGenerator.getObject(objectName);

静的メソッドを呼び出しているため、常にObjectのオブジェクトを返します。Tに使用した汎用オブジェクトをコードで明示的に取得するには、

 object = ObjectGenerator.<T> getObject(objectName); 

<T>静的コンテキストで使用されます。非静的呼び出しの場合は必要ありません。

于 2013-02-12T18:24:46.180 に答える