5

私は学校のプロジェクトで初めてジェネリックを使用していますが、メソッドでオブジェクトまたは宣言されたジェネリック要素を返すかどうかに関して、哲学的なジレンマに遭遇しました。

私のOCDは、常に既知の型を返す必要があると言っていますが、そうすると、プリミティブデータ型をクラスにフィードするときにダウンストリームの煩わしさが生じることがわかりました(もちろん、このプロジェクトでは、プリミティブのみをフィードしていますこのクラスに入る)。

これが私が意味することの例です:

public class DansPriorityQueue<E extends Comparable> 
{
    private ArrayList<E> tree;

//Here's a method that returns an object
public Object peek() {
    return tree.get(0);
}

//Here's a method that returns the generic type
public E peek() {
    return tree.get(0);
}

(参考までに..私はこのJDKクラスを自分で実装する必要がありますが、幸いなことに、実際のP​​riorityQueueと同じインターフェースを実装する必要はないので、オブジェクトを使用するかジェネリックを使用するかを選択できます)

私の問題

少し汚れているように感じますが、これらのメソッドで E ジェネリック要素ではなく Object を返すように誘惑されます。これは、E を返すと、JUnit が整数値をキャストすることを強制するためです。

DansPriorityQueue<Integer> dpq = new DansPriorityQueue<Integer>();
dpq.add(1);
assertEquals("Expected different value", (Integer) 1, dpq.peek());

一方、オブジェクトを返すとき、自動ボクシングはプリミティブ値のキャストを強制しません。

私が直面している問題のより雄弁な説明は次のとおりです。

http://www.aschroder.com/2009/10/php-1-java-0-the-method-assertequalsobject-object-is-ambiguous-for-the-type/

- - - - - - 編集 - - - - - - - -

ジェネリック型を返し、上記のキャストを使用せずに自動ボックス化された Integer オブジェクトでリストを埋めたときに受け取る実際のエラーは次のとおりです。

---------- 編集終了--------------

質問

  1. 私が使用している一般的な要素ではなく、オブジェクトを返す必要がある、または返さない理由を誰かに教えてもらえますか? どちらにも長所と短所があるようです...ベストプラクティスは何ですか?

  2. オブジェクトを返すと後でキャストの問題が発生する可能性があることを漠然と知っていますが、まだそれらに遭遇していません...これがどのように危険であるかの具体的な例はありますか?

  3. JDK では、Collections メソッドの多くがデフォルトで Object を返すことに気付きました。これは、Java の新しいバージョンで Generics が導入されたためですか、それとも Sun Systems による意識的な決定でしたか?

4

1 に答える 1

8

私が使用している一般的な要素ではなく、オブジェクトを返す必要がある、または返してはならない理由を誰かに教えてもらえますか? どちらにも長所と短所があるようです...ベストプラクティスは何ですか?

場合によります。このような場合、ジェネリック型が必要になります。それ以外の場合、クラスのジェネリック型を定義する意味は何ですか?

オブジェクトを返すと後でキャストの問題が発生する可能性があることを漠然と知っていますが、まだそれらに遭遇していません...これがどのように危険であるかの具体的な例はありますか?

もちろん!

DansPriorityQueue<String> queue = new DansPriorityQueue<String>();
//add items
Float f = (Float)queue.getObject();  //uh-oh! this compiles but will fail 
Float f = queue.getObject(); //generic type, fails during compile

JDK では、Collections メソッドの多くがデフォルトで Object を返すことに気付きました。これは、Generics が Java の新しいバージョンで導入されたためですか、それとも Sun Systems による意識的な決定でしたか?

これは、主に後方互換性のため、またはコレクションを実際に使用して異なる値を含める場合 (たとえば、JTable をレンダリングするための JLabels、String、および Icons の寄せ集め) によるものです。

assertEquals("予想される異なるサイズ", (整数) 2, dpq.size());

これは問題になるべきではないと思います。dpq.size() は、優先キューに格納されているものに関係なく、int を返す必要があります。これは一般的な値ではありません。

次のようなものを作成できます

DansPriorityQueue<Double> queue = new DansPriorityQueue<Double>();
for(double d = 0; d < 10; d+=1.0)
    queue.add(d);

それは問題を引き起こさないはずですよね?

于 2013-11-08T16:00:41.200 に答える