我有这个Java代码。
public <T> T readObjectData(ByteBuffer buffer, Class<T> type) {
...
T retVal = (T) summaries;
return retVal;
如何解释此代码?为什么我们需要public <T> T
而不是public T
?
如何将参数提供给第二个参数(Class<T> type
)?
答案 0 :(得分:43)
这声明了readObjectData
方法通用,带有一个类型参数T
。
public <T> ...
然后返回类型为T
。
... T readObjectData(...
如果没有初始<T>
,这是通用类型声明,则符号T
将是未定义的。
在参数列表中,Class<T> type
是其中一个参数。因为返回类型和此参数都引用T
,这可以确保如果您传入Class<String>
,则会返回String
。如果您传入Class<Double>
,则会返回Double
。
要传入参数,请传入任何Class
个对象,例如String.class
。
答案 1 :(得分:25)
<T>
部分声明泛型类型参数 T
。如果您要省略此部分,编译器可能会抱怨类型T
不存在。
在这种情况下,T
用作实际类型的占位符,只有在使用非泛型类型参数实际调用该方法时才会确定。
public <T> T readObjectData(...
^ ^
| + Return type
+ Generic type argument
答案 2 :(得分:16)
<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
,这是一种不好的做法。这是发明仿制药的一个原因。
答案 3 :(得分:6)
您可能会对类似且更常见的声明感到困惑:
"<T>"
在上述情况下,私人(private <T> T myMethod(T a)
)之后无需T
因为它使用的MyClass<T>
与类class MyClass<T> {
private <T> T myMethod(T a){
return a;
}
}
中定义的class MyClass<T1> {
private <T2> T2 myMethod(T2 a){
return a;
}
}
相同
更多,如果你写
{{1}}
那么意思是myMethod返回类型(可能)与MyClass类型不同。好像你写的那样:
{{1}}
致谢:从&#34; Kanagavelu Sugumar&#34;给How to use Class<T> in Java?
的更长答案中取得榜样答案 4 :(得分:0)
这是 JsonPath 使用的模式,它允许您使用语义,例如:
String author = JsonPath.read(json, "$.store.book[0].author");
List<String> authors = JsonPath.read(json, "$.store.book[*].author");
这是最接近动态编程语言(例如 Javascript)中使用的鸭子类型的方法,目前可以使用 Java 来完成。