3

「this.<Double>getAnything(int flag)」のような通常の表記法を使用せずに値を割り当てる

private <T> T getAnything(int flag) {
    Object o = null;
    if (flag==0)
        o=new String("NewString");
    else if (flag==1)
        o=new Double(0D);
    return (T)o;
}


private void someMethod() {
    String s = getAnything(0);
    Double d = getAnything(1);
}

以前は、メソッドの戻りオブジェクトと受信型の単純なキャストだけで十分だったので、受信側オブジェクトに一般的な表記がないため、はるかに似ていて高速に記述できます。これに関する他のヒントはありますか?

4

2 に答える 2

5

タイプセーフについて

何をしようとしているのかは明確ではありませんが、コードにはタイプセーフがまったくないことを指摘する必要があります。

Double d = getAnything(0);
// compiles fine, but throws ClassCastException at run time

これは、そもそもジェネリックを使用する目的に反します。

この声明を書いたときに、この危険性を導入しました。

return (T)o; // warning: Type safety: Unchecked cast from Object to T

関連する質問

こちらもご覧ください

  • 有効な Java 2nd Edition、項目 24: 未チェックの警告を削除する

タイプセーフな異種コンテナについて

おそらく、Josh Bloch が Typesafe Heterogeneous Container と呼んでいるもののようなものが必要になるでしょう。以下はニール・ガフターのブログからの引用です。

Josh の 2006 年の JavaOne 講演から、THC パターンで型トークンを使用する API の単純だが完全な例を次に示します。

public class Favorites {

    private Map<Class<?>, Object> favorites =
        new HashMap<Class<?>, Object>();

    public <T> void setFavorite(Class<T> klass, T thing) {
        favorites.put(klass, thing);
    }
    public <T> T getFavorite(Class<T> klass) {
        return klass.cast(favorites.get(klass));
    }

    public static void main(String[] args) {
        Favorites f = new Favorites();
        f.setFavorite(String.class, "Java");
        f.setFavorite(Integer.class, 0xcafebabe);

        String s = f.getFavorite(String.class);
        int i = f.getFavorite(Integer.class);
    }
}

このパターンを使用すると、型安全性が得られます。int i = f.getFavorite(String.class);コンパイルされませ(これは良いことです!)。

こちらもご覧ください


オートボクシングについて

オートボクシングは、プリミティブint型から参照型への暗黙的な変換Integerです。autounboxing は逆の変換です。前述の質問は、オートボクシングとは何の関係もありません。

こちらもご覧ください

関連する質問

于 2010-07-10T16:22:48.160 に答える
1

オートボクシングと型推論を混同していると思います。

型推論は、メソッドを呼び出すときに使用される変数から、コンパイラがジェネリック メソッドで使用する必要がある型を独自に判断できる場合です。

たとえば、次のメソッドがあるとします。

public <T extends SomeClass> T process(T obj) {
    // call some methods of SomeClass on obj to process it here
    return obj;
}

そしてそれを次のように呼び出します:

SomeChildClass a = new SomeChildClass(); // SomeChildClass extends SomeClass
a = process(a);

推論される型は SomeChildClass になります。

例のように、型はパラメーターまたは戻り値の型から推測できます。しかし、コンパイラがどの型を使用すべきかが常に明らかであるとは限りません。その場合は、説明した方法を使用して型を強制できthis.<Double>getAnything(int flag)ます。これは通常、次のような状況で発生します。

public <T> List<T> getSomeList() {
    // implementation
}

public void processList(List<SomeClass> list) {
     // implementation
}

と呼び出し

processList(getSomeList()); // compiler error: cannot convert List<Object> to List<SomeClass>

このような場合、型パラメータを強制する必要があるかもしれません。

以上のことを踏まえて、polygenelubricants があなたのコードに関していくつかの非常に良い点を指摘し、オートボクシングとは何かを説明しているので、polygenelubricants が言ったことすべてを考慮してください (int の場合は Integer、double の場合は Double などのプリミティブ ラッパー クラスに関連しています)。

于 2010-07-19T08:27:28.037 に答える