17

編集:私はアイデアを得るために少し例を変更しました:

好き

 <Integer or Float>

...共通のインターフェースを作成し、それを実装するためにIntegerとFloatのサブクラスを作成する必要はありません

そうでなければ、このようなものはおそらくもっと意味があり、役に立つでしょう

 <E extends Number> <E = (Integer|Float)>

もしも ?ワイルドカードはなぜ特定のタイプを制限することを許可すべきではないのですか?

4

3 に答える 3

12

それは不可能であり、私はそれにほとんど価値を見ません。ジェネリックスを使用して、コレクションなどで型を制限します。このor場合、演算子を使用すると、両方の最も具体的なスーパータイプについて知っているのと同じくらい、タイプについて知っていますObject。では、なぜ単に使用しないのObjectですか?

仮説:

List<E extends String or Number> list = //...

の種類はlist.get(0)何ですか?それString ですか Number?しかし、そのようなタイプの変数を持つことはできません。ありえないString、ありえないNumber-ありえない… Object

更新:問題の例を次のように変更したため:

<Integer or Float>

なぜあなたはただ言わないのですか:

<Number>

?とNumberを簡単に抽出できるメソッドがあることに注意してください。本当に正確なタイプが必要ですか?floatValue()intValue()


演算子を使用できることに注意してください。and

<E extends Serializable & Closeable>

そして、それは完全に理にかなっています-またはが必要なE場所でタイプの変数を使用できます。つまり、との両方を拡張する必要があります。参照:複数のクラスを使用したJavaGenericsワイルドカードSerializableCloseableESerializableCloseable

于 2012-07-24T14:44:50.910 に答える
10

In very extreme cases (pre-Java 7 without AutoCloseable), I would have liked to be able to do that, too. E.g.

<E extends Connection or Statement or ResultSet>

That would've allowed me to call E.close(), no matter what the actual type was. In other words, E would contain the "API intersection" of all supplied types. In this case it would contain close(), and all methods from java.sql.Wrapper and java.lang.Object.

But unfortunately, you cannot do that. Instead, use method overloading, e.g.

void close(Connection c);
void close(Statement s);
void close(ResultSet r);

Or plain old instanceof

if (obj instanceof Connection) {
    ((Connection) obj).close();
}
else if (obj instanceof Statement) { //...

Or fix your design, as you probably shouldn't have to intersect APIs of arbitrary types anyway

于 2012-07-24T14:48:10.467 に答える
1

I don't see a real use for it... But anyways, I believe the closest you'd get to it is extending common interfaces for the possible implementations.

于 2012-07-24T14:46:53.397 に答える