0

ジェネリック型(A、B)を使用する2つのクラスがあります。私の質問は-Bの内側から最初のジェネリック型(TA)を操作するための最良の方法は何ですか?簡単な例を次に示します。

public class A<TListItemsType>
{
    List<TListItemsType> list = new LinkedList<TListItemsType>();
    public List<TListItemsType> getList()
    {
        return list;
    }   
}
public class B<TContainderType extends A>
{
    TContainderType temp = null;
    public B(TContainderType cont)
    {
        temp=cont;  
    }
    public void DoWork()
    {
        for (TListItemsType item : temp.getList())
        {
            System.out.println(item);
        }
    }
}

私はここで提案された解決策を試しました-

public class B<TContainderType extends A<TListItemsType>>
{
    TContainderType temp = null;
    public B(TContainderType cont)
    {
        temp=cont;  
    }
    public void DoWork()
    {
        for (TListItemsType item : temp.getList())
        {
            System.out.println(item);
        }
    }
}

また、整数や文字列などの事前定義された型を使用している限り機能しますが、残念ながら、コンパイラはジェネリックをクラス名として認識しないため、これは機能しません。

そこで、さらに進んで、別のジェネリック型を構成し、それをextends内で使用しようとしました。

public class B<TListItemsType, TContainderType extends A<TListItemsType>>
{
    TContainderType temp = null;
    public B(TContainderType cont)
    {
        temp=cont;  
    }
    public void DoWork()
    {
        for (TListItemsType item : temp.getList())
        {
            System.out.println(item);
        }
    }
}

そしてそれは実際に機能しますが、それは正しいにおいがしません。別のジェネリック型で使用されるジェネリック型を使用する別の方法はありますか?

4

2 に答える 2

1

あなたがそれを使ってそれをした方法はB<TListItemsType, TContainderType extends A<TListItemsType>>私にはよく見えます...

これが理にかなっている理由は、Bクラスが実際にそれを記述するために2つのパラメーターを必要とするためTListItemsTypeですTContainderType。実際、内部の関数でTListItemsType明示的に使用していることさえあります。したがって、パラメータとして渡す必要があるのは公正なことです。そうしないと、次のようにクラス定義を記述できるため、コンパイラは関数内で何を意味するのかさえわかりません。DoWork()BDoWork()

public class B<TWorkItemType, TContainderType extends A<TWorkItemType>>
{
    //...

    public void DoWork()
    {
        for (TWorkItemType item : temp.getList())
        {
            System.out.println(item);
        }
    }
}

(タイプの名前を完全に変更したことに注意してください。ただし、Bではなく、でA!)

TListItemsTypeの定義で使用されているのと同じ名前を使用する必要があるだけの場合Aは、ジェネリックで実行できることはかなり制限されます。たとえば、あるタイプのextendsList<E>と別のタイプのextendsEnum<E>はどちらも<E>総称識別子として使用されているため、これらを受け入れることはできませんでした。

今はいい匂いがすることを願っています...:)

于 2012-12-04T16:20:54.953 に答える
0

あなたの質問から、あなたがどのような要件を必要とし、何のためにTListItemsTypeを使用する必要があるのか​​は本当に不明確です。TListItemsTypeを意味のある方法で使用する必要が本当にない場合(例のように)、それを削除してTContainderTypeを拡張することができますA<?>

public class B<TContainderType extends A<?>>
{
    TContainderType temp = null;
    public B(TContainderType cont)
    {
        temp=cont;  
    }
    public void DoWork()
    {
        for (Object item : temp.getList())
        {
            System.out.println(item);
        }
    }
}

さらに言えば、TContainderTypeを返したり、型パラメーターなどで使用したりしない場合は、次のことを排除することもできます。

public class B
{
    A<?> temp = null;
    public B(A<?> cont)
    {
        temp=cont;  
    }
    public void DoWork()
    {
        for (Object item : temp.getList())
        {
            System.out.println(item);
        }
    }
}

したがって、それはすべてあなたが何をする必要があるかに依存します。あなたの例はあまり効果がないので、そこから多くのものを削除することは可能ですが、それは実際に必要なものではないかもしれません。

于 2012-12-04T19:41:38.913 に答える