46

我有这个 Java 代码。

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

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

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

4

5 回答 5

58

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

public <T> ...

那么返回类型是T.

... T readObjectData(...

如果没有作为泛型类型声明的 initial <T>,符号T将是未定义的。

在参数列表中,Class<T> type是参数之一。因为返回类型和这个参数都引用了T,这保证了如果你传入 a Class<String>,那么它将返回 a String。如果你传入 a Class<Double>,那么它将返回 a Double

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

于 2013-04-08T20:42:19.927 回答
35

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

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

public <T> T readObjectData(...
        ^  ^
        |  + Return type
        + Generic type argument
于 2013-04-08T20:42:21.537 回答
20

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

因为方法定义如下:

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

你可以这样称呼它:

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

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

public Object readObjectData(ByteBuffer)

它的用法看起来像:

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

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

于 2013-04-08T20:47:10.153 回答
13

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

class MyClass<T> {
   private  T myMethod(T a){
       return  a;
   }
}

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

因为T它使用的和类中定义的一样MyClass<T>

更重要的是,如果你写

class MyClass<T> {
   private <T> T myMethod(T a){
       return  a;
   }
}

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

class MyClass<T1> {
   private <T2> T2 myMethod(T2 a){
       return  a;
   }
}

学分:以“Kanagavelu Sugumar”对How to use Class<T> in Java?

于 2016-10-19T01:57:03.663 回答
0

这是JsonPath使用的模式,它允许您使用以下语义:

String author        = JsonPath.read(json, "$.store.book[0].author");
List<String> authors = JsonPath.read(json, "$.store.book[*].author");

这是最接近动态编程语言(例如 Javascript)中使用的鸭子类型的东西,目前可以用 Java 完成。

于 2021-02-09T12:30:09.157 回答