java 在泛型方法参数中键入 T 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15549958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:01:30  来源:igfitidea点击:

type T parameters in generic method arguments

javagenerics

提问by AmitG

Suppose the following classes are defined:

假设定义了以下类:

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

You can write a generic method to draw different shapes:

您可以编写一个通用方法来绘制不同的形状:

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

The Java compiler replaces T with Shape:

Java 编译器将 T 替换为 Shape:

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

My Question is, if we define directly // 3 in our class then we still be able to pass Shape, Circleand Rectanglereference to method at //3. Then why do we need to write // 2 generic method with type parameter <T extends Shape>which is untimately going to be same as //3 ?

我的问题是,如果我们在我们的类中直接定义 // 3 那么我们仍然可以传递Shape,CircleRectangle引用 //3 处的方法。那么为什么我们需要编写 // 2 带有类型参数的泛型方法,<T extends Shape>该方法显然与 //3 相同?

You can refer this link with same example : http://docs.oracle.com/javase/tutorial/java/generics/genMethods.html

您可以使用相同的示例参考此链接:http: //docs.oracle.com/javase/tutorial/java/generics/genMethods.html

回答by dasblinkenlight

You may or may not need it. You need it if your method has to deal with other objects of the type Tthat must match the type of T extends Shapeexactly, for example:

您可能需要也可能不需要它。如果您的方法必须处理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
}

Above, passing Shapewould not be enough, because we wouldn't be able to make the shadow of the exactly same type.

上面,通过Shape是不够的,因为我们将无法制作完全相同类型的阴影。

In case when there is no such requirement, a simple Shapewould be sufficient.

如果没有这样的要求,一个简单的Shape就足够了。

回答by Andy Thomas

In this particular case, you don't need a generic method.

在这种特殊情况下,您不需要通用方法。

But you can do more in a generic method than call a dynamically linked method on its arguments.

但是您可以在泛型方法中做更多的事情,而不是在其参数上调用动态链接的方法。

For example, you might have a generic method that accepts and returns a collection of T elements. Parameterizing it by type allows you to use it on multiple collection types.

例如,您可能有一个接受并返回 T 元素集合的通用方法。按类型参数化它允许您在多种集合类型上使用它。

Other examples where generic methods are useful are in this Java tutorial.

通用方法有用的其他示例在本Java 教程中

回答by Alexei Kaigorodov

In your example, //3 is indeed the same as //2. But in other usecases, generic type may be useful:

在您的示例中,//3 确实与//2 相同。但在其他用例中,泛型类型可能很有用:

  • you want to return value from the method, of the same type as the argument

  • you have 2 or more parameters and want to set restriction that they must be of the same type

  • 您想从方法中返回与参数类型相同的值

  • 您有 2 个或更多参数并希望设置限制,即它们必须属于同一类型

回答by Hyman

The difference is that the kind of polymorphism you are using.

不同之处在于您使用的多态性类型。

In the generic case you are using parametric polymorphismwhile in the second one you are using polymorphism by subtype. Actually you first case uses both kind of polymorphism.

在一般情况下,您使用参数多态性,而在第二种情况下,您使用subtype 多态性。实际上,您的第一种情况使用了两种多态性。

Now, they could be similar in some aspects but they are not the same. A practical example:

现在,它们在某些方面可能相似,但它们并不相同。一个实际例子:

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

You can see that in the first case, not having a type parameter, I can't manage a list of a specific subtype of Shape, I can only manage an eterogeneous list of shapes but I'm unable to force any specific one on it. So I don't have any compile time juice that forbids me from adding a Triangleand a Rectangleto the shapes.

您可以看到,在第一种情况下,没有类型参数,我无法管理 Shape 的特定子类型的列表,我只能管理形状的异类列表,但我无法强制任何特定的形状. 所以我没有任何编译时汁液禁止我将 aTriangle和 a添加Rectangleshapes.

class ShapeDecorator {
  private Shape shape;

  ..

  Shape get() { return shape; }
}

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

  T get() { return shape; }
}

Here is another example, in this case you could write a generic decorator which is able to return a type T without the need of any cast. This can be useful in many situations in which having the common ancestor as subtype is not enough.

这是另一个示例,在这种情况下,您可以编写一个通用装饰器,该装饰器无需任何强制转换即可返回类型 T。这在许多情况下很有用,在这种情况下,将共同祖先作为子类型是不够的。

回答by benzonico

The main interest is that you can restrict the usage of your method to a specific type of shape in different part of the code.

主要的兴趣是您可以在代码的不同部分将方法的使用限制为特定类型的形状。

At some point you may want to parametrize it to draw only Rectangleand in another place only Circleand this will be checked at compile time even if, at runtime, you will pass something of type Shape

在某些时候,您可能希望将其参数化为仅Rectangle在另一个地方绘制,Circle并且这将在编译时进行检查,即使在运行时您将传递某种类型Shape