有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    首先,如果getAsStringgetAsInt没有进行任何转换(例如,如果所有值都存储为字符串,则会出现这种情况),您可能可以将方法简化为:

    public <T> T getValue(MyObject obj) {
        return (T) obj.value;
    }
    

    这将有一个未经检查的强制转换警告,但这并不比将键入决定权留给调用方更糟糕(因此我只想@SuppressWarnings("unchecked")。如果你的调用者使用了错误的目标类型,他们会在运行时得到一个ClassCastException,我认为这与你当前的合同是一致的。但是,如果希望在自己的方法中引发异常,可以保留c.cast(obj.getAsX())

    有了上述功能,您的呼叫者只需使用:

    String s = getValue(obj);
    int i = getValue(obj);
    

    但是,如果您实际上是在getAs...方法中转换数据,那么在分派到正确的getAsX方法之后,您将需要在泛型getter中强制转换,至少转换为ProGu suggested(即每个分支中的return c.cast(obj.getAsX())