java如何使用泛型来提供“通用getter方法”?
这个问题更具理论性(我想做的事情更复杂,但这是我一直坚持的部分),所以为这个可能没有多大意义的人为例子道歉
假设我有一个类,它有以不同形式返回其值的方法:
public class MyObject {
public String getAsString() {...}
public int getAsInt() {...}
// and so on
}
我试图创建一个方法,允许我指定通过其参数调用哪个MyObject方法。比如:
public <T> T getValue(MyObject obj, Class<T> c) {
if (c == String.class) {
return obj.getAsString();
} else if (c == Integer.class) {
return obj.getAsInt();
} // and so on
}
那么我想这样调用这个方法,假设obj是一个MyObject:
String s = getValue(obj, String.class);
int i = getValue(obj, Integer.class);
// and so on
我在getValue方法中遇到编译错误“类型不匹配:无法从字符串转换为T”(对于Integer也是如此)。显然,我只是没有完全理解泛型,但我认为这是泛型背后的一般想法——在这里,我通过参数c指定(或试图指定,至少是)T的真实类型。我做错了什么
# 1 楼答案
首先,如果
getAsString
和getAsInt
没有进行任何转换(例如,如果所有值都存储为字符串,则会出现这种情况),您可能可以将方法简化为:这将有一个未经检查的强制转换警告,但这并不比将键入决定权留给调用方更糟糕(因此我只想
@SuppressWarnings("unchecked")
。如果你的调用者使用了错误的目标类型,他们会在运行时得到一个ClassCastException
,我认为这与你当前的合同是一致的。但是,如果希望在自己的方法中引发异常,可以保留c.cast(obj.getAsX())
有了上述功能,您的呼叫者只需使用:
但是,如果您实际上是在
getAs...
方法中转换数据,那么在分派到正确的getAsX方法之后,您将需要在泛型getter中强制转换,至少转换为ProGu suggested(即每个分支中的return c.cast(obj.getAsX())
)