13

次のクラスが定義されているとします。

class Shape { }
class Circle extends Shape {  }
class Rectangle extends Shape { }  //  1

さまざまな形状を描画するための一般的なメソッドを作成できます。

public static <T extends Shape> void draw(T shape) { }   // 2

Java コンパイラは T を Shape に置き換えます。

public static void draw(Shape shape) {  } // 3

私の質問は、クラスで // 3 を直接定義した場合でも、 を渡しShape、//3 でメソッドを参照Circleできるということです。Rectangleでは、なぜ<T extends Shape>//3 と同じになる型パラメーターを持つ // 2 ジェネリック メソッドを記述する必要があるのでしょうか。

このリンクを同じ例で参照できます: http://docs.oracle.com/javase/tutorial/java/generics/genMethods.html

4

5 に答える 5

12

必要な場合と必要でない場合があります。メソッドが、の型と正確にT一致する必要がある型の他のオブジェクトを処理する必要がある場合に必要です。次に例を示します。T extends Shape

public static <T extends Shape> void drawWithShadow(T shape, Class<T> shapeClass) {
    // The shadow must be the same shape as what's passed in
    T shadow = shapeClass.newInstance();
    // Set the shadow's properties to from the shape...
    shadow.draw(); // First, draw the shadow
    shape.draw();  // Now draw the shape on top of it
}

Shape上記では、まったく同じタイプの影を作成できないため、渡すだけでは十分ではありません。

そのような要件がない場合は、単純なShapeもので十分です。

于 2013-03-21T14:17:22.193 に答える
2

この特定のケースでは、ジェネリック メソッドは必要ありません。

ただし、ジェネリック メソッドでは、その引数に対して動的にリンクされたメソッドを呼び出すよりも多くのことができます。

たとえば、T 要素のコレクションを受け取って返すジェネリック メソッドがあるとします。型ごとにパラメーター化すると、複数のコレクション型で使用できます。

ジェネリック メソッドが役立つその他の例は、このJava チュートリアルにあります。

于 2013-03-21T14:16:37.260 に答える
2

あなたの例では、 //3 は実際に //2 と同じです。ただし、他のユースケースでは、ジェネリック型が役立つ場合があります。

  • 引数と同じ型のメソッドから値を返したい

  • 2 つ以上のパラメーターがあり、同じ型でなければならないという制限を設定したい場合

于 2013-03-21T14:22:55.980 に答える
2

違いは、使用しているポリモーフィズムの種類です。

一般的なケースでは、パラメトリック ポリモーフィズム を使用していますが、2 番目のケースでは、サブタイプによるポリモーフィズムを使用しています。実際、最初のケースでは両方の種類のポリモーフィズムを使用しています。

さて、それらはいくつかの点で類似している可能性がありますが、同じではありません。実際の例:

List<Shape> shapes;
List<T extends Shape> specificShapes;

タイプ パラメータがない最初のケースでは、Shape の特定のサブタイプのリストを管理できず、不均一な形状のリストしか管理できませんが、特定のものを強制することはできません。 . Triangleしたがって、 aと aRectangleを に追加することを禁止するコンパイル時のジュースはありませんshapes

class ShapeDecorator {
  private Shape shape;

  ..

  Shape get() { return shape; }
}

class ShapeDecorator<T extends Shape> {
  private T shape;

  T get() { return shape; }
}

別の例を次に示します。この場合、キャストを必要とせずに型 T を返すことができる汎用デコレーターを作成できます。これは、サブタイプとして共通の祖先を持つだけでは不十分な多くの状況で役立ちます。

于 2013-03-21T14:24:22.203 に答える
1

主な関心事は、コードのさまざまな部分でメソッドの使用を特定のタイプの形状に制限できることです。

ある時点で、描画のみRectangle、別の場所のみにパラメーター化するCircleことができます。これは、実行時に何かの型を渡す場合でも、コンパイル時にチェックされます。Shape

于 2013-03-21T14:17:31.203 に答える