关于泛型:如何在Java中解释“public < T > T readObjectData(… Class < T > type)”?

How to interpret “public T readObjectData(… Class type)” in Java?

我有这个Java代码。

1
2
3
4
public < T > T readObjectData(ByteBuffer buffer, Class< T > type) {
...
T retVal = (T) summaries;
return retVal;

如何解释这段代码? 为什么我们需要public < T > T而不是public T

如何将参数赋给第二个参数(Class< T > type)?


这声明了readObjectData方法泛型,带有一个类型参数T

1
public < T > ...

然后返回类型是T

1
... T readObjectData(...

如果没有初始< T >(通用类型声明),则符号T将是未定义的。

在参数列表中,Class< T > type是参数之一。因为返回类型和this参数都引用T,这可以确保如果传入Class,它将返回String。如果传入Class,则返回Double

要传入参数,请传入任何Class对象,例如String.class


< T >部分声明了泛型类型参数T。如果您省略此部分,编译器可能会抱怨类型T不存在。

在这种情况下,T用作实际类型的占位符,只有在使用非泛型类型参数实际调用方法时才会

1
2
3
4
public < T > T readObjectData(...
        ^  ^
        |  + Return type
        + Generic type argument


< T >是参数类。没有名为T的类。您可以将此方法用于通过名为type的第二个方法参数指定的任何类。

因为方法定义如下:

public < T > T readObjectData(ByteBuffer buffer, Class< T > type)

你可以按下面的说法调用它:

MyClass obj = o.readObjectData(buffer, MyClass.class);

请注意,您不必将readOjectData()的返回值转换为MyClass。曾几何时,在java 5之前,这个方法将被定义为:

public Object readObjectData(ByteBuffer)

它的用法如下:

MyClass obj = (MyClass)o.readObjectData(buffer);

由于铸造可能导致ClassCastException这是一种不好的做法。这是发明仿制药的一个原因。


您可能会对类似且更常见的声明感到困惑:

1
2
3
4
5
class MyClass< T > {
   private  T myMethod(T a){
       return  a;
   }
}

在上述情况下,私有后不需要"< T >"(private < T > T myMethod(T a))

因为它使用的T与类MyClass< T >中定义的相同

更重要的是,如果你写

1
2
3
4
5
class MyClass< T > {
   private < T > T myMethod(T a){
       return  a;
   }
}

那么意思是myMethod返回类型(可能)与MyClass类型不同。好像你写了这个:

1
2
3
4
5
class MyClass<T1> {
   private <T2> T2 myMethod(T2 a){
       return  a;
   }
}

致谢:从"Kanagavelu Sugumar"中如何使用Java中的Class < T >获得更长的答案?