我们可以创建具有通用返回类型的方法吗,它如何评估在编译时返回哪种类型?

时间:2019-03-11 10:05:20

标签: java generics

我看到编译器允许以下方法。但是谁能解释在编译时如何确定返回类型,以及T的值是什么。 您还可以给我参考文档或视频,以便我进一步了解Java编译器将如何在内部确定泛型类型。

public <T> T getValue(String abc) throws Exception {
        if(abc.equals("x")){
            return (T) new String[]{"x","y","z"};
        } else {
            return (T) "abc";
        }
    }

2 个答案:

答案 0 :(得分:2)

在编译时有类型擦除过程。来自javadoc:

  

在类型擦除过程中,Java编译器将擦除所有类型参数,如果类型参数是有界的,则将每个参数替换为其第一个边界;如果类型参数是无界的,则将其替换为对象

因此,在您的示例中,所有T都将替换为Object类型。但是在执行期间,它将强制转换为您指定的类型。例如:

Integer value = obj.<Integer>getValue("string");

没有编译时错误,但是在运行时它将尝试应用强制转换return (Integer) "abc";,您将获得ClassCastException

详细了解Erasure Generic typeErasure of Generic Methods

答案 1 :(得分:0)

您不能一般地这样做。

最好的办法是使用非泛型方法,返回一个公共超类-在这种情况下,为Object

public Object getValue(String abc) throws Exception {
    if(abc.equals("x")){
        return new String[]{"x","y","z"};
    } else {
        return "abc";
    }
}

这使调用者承担了将对象转换为适当类型的负担,您可以避免这种情况。但是请注意,您当前的方法也可以这样做,因为没有什么可以阻止他们编写此代码:

String s = getValue("x");
String[] arr = getValue("x");

这两个都很好,但是其中之一将在运行时失败。调用者必须以某种方式知道哪些调用将返回String,哪些调用将返回String[]

强制他们进行投射的优势在于,他们可以看到投射,并知道他们将必须保重。

更好的方法是在所有情况下都返回相同类型的值:改为返回new String[]{"abc"}