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
。
public <T> ...
T
。... T readObjectData(...
<T>
,也就是泛型类型声明,符号 T
将是未定义的。在参数列表中,Class<T> type
是其中之一。由于返回类型和此参数都引用了 T
,因此这确保了如果您传递一个 Class<String>
,则它将返回一个 String
。如果您传递一个 Class<Double>
,则它将返回一个 Double
。要传递参数,请传递任何 Class
对象,例如 String.class
。<T>
部分声明了一个 泛型类型参数 T
。如果您省略此部分,编译器可能会抱怨 T
类型不存在。
在这种情况下,T
作为实际类型的占位符,该类型只有在使用非泛型类型参数调用方法时才确定。
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
,这是一种不好的做法。这就是泛型发明的原因。
你可能会对类似且更常见的声明感到困惑:
class MyClass<T> {
private T myMethod(T a){
return a;
}
}
"<T>"
"(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”在如何在Java中使用Class<T>?问题的更长回答示例。
这是JsonPath使用的模式,它允许您使用语义,例如:
String author = JsonPath.read(json, "$.store.book[0].author");
List<String> authors = JsonPath.read(json, "$.store.book[*].author");
这是在动态编程语言中最接近鸭子类型的东西,比如JavaScript,目前也可以用Java来实现。