2

Paintを拡張するパラメータを持つジェネリッククラスがあります。最初のコンストラクターで手動でTにキャストする必要がある理由がよくわかりません。私は何が間違っているのですか?または、これはコンパイラが安全なキャスト自体を判断できない場合ですか?

public class XYPlot <T extends Paint> extends AbsPlot implements XYChartElement {
public XYPlot(AbsSeries series){
    setUp(series, (T) new Paint(DEFAULT_PAINT));//TODO
}

public XYPlot(AbsSeries series, T paint){
    setUp(series, paint);
}

private void setUp(AbsSeries series, T paint){
    if(series == null) throw new NullPointerException("Series is null");
    setSeries(series);
    setPaint(paint);
}
4

2 に答える 2

5

最初のコンストラクターで手動で T にキャストする必要がある理由が本当にわかりません。

すべきではありません-Paintそもそもインスタンスを作成するべきではありません。が正確にでない限り、それはのインスタンスにはPaint なりません。単一の型引数に対してのみ適切に機能するジェネリック クラスは、そもそもジェネリックであってはなりません。TT Paint

T構築中のインスタンスが必要な場合は、呼び出し元がインスタンスを渡すか、リフレクションを使用してコンストラクターを調べて適切なコンストラクターを呼び出すことができるようにする必要がありますClass<T>

あなたがしていることのより単純なバージョンを見てみましょう。うまくいけば、なぜそれが間違っているのかがわかります。

public class Wrapper<T extends Object>
{
    private final T value;

    public Wrapper()
    {
        value = (T) new Object();
    }

    public T getValue()
    {
        return value;
    }
}

ここではObject代わりにPaint- を使用していますが、それ以外は基本的に同じです。

今それを呼ぶと:

Wrapper<String> wrapper = new Wrapper<String>();
String text = wrapper.getValue();

...それが何をすることを期待しますか?

そもそもクラスをジェネリックにした理由は根本的に明らかではありませんが、あなたが取っているアプローチには本質的に欠陥があります。

于 2012-11-19T06:50:08.853 に答える
0
setUp(series, (T) new Paint(DEFAULT_PAINT));

これは、実際の引数TPaintそれ自体である場合にのみ安全です。型引数が代わりに何らかのサブクラスである場合、それは CCEになりPaintます。

于 2012-11-19T06:51:29.823 に答える