5

私は現在、Java をブラッシュアップし、Generics について調べています。それらは私のJavaクラスではあまり扱われていなかったので、私はまだそれについて頭を悩ませているので、答えるときはそのことを覚えておいてください.

まず第一に、私がやろうとしていることは不可能だと確信しています。しかし、自分の考えのどこが間違っているのか、自分のやりたいことを実現するにはどうすればよいのかを知りたいです。

私がやろうとしているのは、インスタンス化された型に関する知識を持たない別のクラスからジェネリック インターフェイスを実装するオブジェクトを操作することです。したがって、次のようなクラスがあります。

public interface CalledInterface<E> {
    public E get() { ... }
    public set(E e) { ... }
}


public class Called implements CalledInterface<String> {
    ...
}

今、私がやりたいことは次のとおりです。

public class Caller {
    protected CalledInterface<?> c;

    public Caller (CalledInterface<?> arg) {
        c = arg;
    }

    public void run(){
        // I can do this:
        c.set(c.get());

        // But I'd want to be able to do something like:
        <?> element = c.get();
        c.set(element);
    }
}

私の考えに根本的な欠陥があるとすれば、それは何ですか? そして、私はむしろどのようなアプローチをとるべきですか?

4

3 に答える 3

8

まず第一に、ジェネリックはランタイムではなくコンパイル時のものであることを覚えておいてください。

今、あなたCallerが定義しCalled cた . Calledを実装するように定義されているため、コンパイル時に次のメソッドがCalledInterface<String>自動的に生成されます。Called

String get();
void set(String e); //i assume you wanted to return void

したがって、本質的にこれは意味がありません。

<?> element = c.get();

このクラスは、内部でジェネリックを使用しCallerていることさえ認識していません。そのため、文字列を処理するだけです。CalledCalled

アップデート

コメントに基づいて、直接Caller使用したくないので、最初に使用する必要があるのは、のタイプをそれに変更することです。この場合、ジェネリックを使用しないでください。ジェネリックの要点は、同じクラスが異なるシナリオで異なる型 (コンパイル時に決定される) で使用され、コードを繰り返さずに型を強制することであるためです。CalledCalledInterfacec

Caller私が正しく理解していれば、文字列の使用を制限したくないのでCalledInterface、ジェネリックを使用しないように変更し、メソッドを次のように変更する必要があります。

Object get();
void set(Object o);

これは、Java 1.4 の Generics の前に私たちが行っていた方法です。明らかに型安全性を持たないというリスクを冒すので、必要なものが本当にデザインに意味があるかどうかを考えてくださいObject。その方法)。

一方、cメンバー (およびのコンストラクター引数Caller) を次のように変更するだけの場合:

CalledInterface<String> c;

実装ではなくCallerとやり取りすると同時に、タイプセーフになります。CalledInterfaceしたがって、インスタンスを渡してCalledに設定することもできますc

于 2012-12-06T12:09:03.027 に答える
1

編集後:

    // I can do this:
    c.set(c.get());

いいえ、できません。cであるとコンパイルされませんCalledInterface<?>。(あなたもそれを試しましたか?)

これを行うには、「キャプチャ ヘルパー」を使用できます。

private static <T> void helper(CalledInterface<T> c) {
    c.set(c.get());
}
public void run(){
    helper(c);
}

2番目の問題も解決します:

private static <T> void helper(CalledInterface<T> c) {
    T element = c.get();
    c.set(element);
}
public void run(){
    helper(c);
}
于 2012-12-06T19:45:42.953 に答える