java中带泛型的类文字

问题描述 投票:-1回答:1

经过以下链接,即link1link2,我面临着提供一个类文字作为参数的挑战。以下是我的代码,我得到编译错误如下:

class GenericService {
    public <T> List<T> serve(Class<T> clazz) {
        if(clazz == Set.class) {
            Set<String> inputs = new HashSet<>();
            return implement(inputs, clazz);
        } else if(clazz == Map.class) {
            Map<String, Object> inputs = new HashMap<>();
            return implement(inputs, clazz);
        }
    }

    public List<Set<String>> implement(Set<String> inputs, Type clazz) {
        //Based on clazz decide that the output will be of type 'List<Set<String>>'
        List<Set<String>> result = new ArrayList<>();
        //do something with inputs
        //populate result
        return result;
    }

    public List<Map<String, Object>> implement(Map<String, Object> inputs, Type clazz) {
        //Based on clazz decide that the output will be of type 'List<Map<String, Object>>' 
        List<Map<String, Object>> result = new ArrayList<>();
        //do something with inputs
        //populate result
        return result;
    }
}

有几点需要注意:

  1. 我只能传递List.classMap.class而不是指定泛型类型。基于此确定结果类型(未提供实现细节)。
  2. 因为,结果类型是使用class literal派生的,我得到以下编译时错误。

Type mismatch: cannot convert from List<Set<String>> to List<T>

Type mismatch: cannot convert from List<Map<String,Object>> to List<T>

我怎样才能使这个工作?

java generics spring-rest
1个回答
1
投票

首先要做的事情。

  1. 我只能传递List.class或Map.class,而不是指定泛型类型。基于此确定结果类型(未提供实现细节)。

您不能在类参数中指定泛型类型,因为(仔细阅读)运行时期间不存在泛型类型信息。在运行时,你没有得到List<String>List<Integer>等。在运行时,一切都只是简单的List


关于它为何如此的简短历史。

仿制药直到Java 5才存在。所以当仿制药作为Java 5的一部分引入时,他们最不想做的就是告诉全世界从List改为List<String>List<Whatever_Object_They_Want>

例如,假设您使用的是使用Java 4编译的依赖项,并且此依赖项中的方法只返回普通的旧List,您仍然可以使用您的代码调用该方法,该代码是用Java 5编译的。你不能把它强制转换为任何泛型类型。

想象一下,如果Java5开始只支持像List <>这样的泛型类型而不支持普通的旧List。您必须依赖所有供应商来提供在Java5中编译的依赖项。这会导致混乱。因此,为了避免这种情况,并保持与使用以前版本的java的向后兼容性,当代码被编译为字节代码时,通用类型信息被剥离。这叫做Type Erasure

正是由于这个原因,您无法使用任何集合类型的类文字指定泛型类型。


来到你的第二点

  1. 因为,结果类型是使用类文字派生的,我得到以下编译时错误。

类型不匹配:无法从List<Set<String>>转换为List<T>

类型不匹配:无法从List<Map<String,Object>>转换为List<T>

如果您浏览泛型文档,通用类型ListList< Map< String, Object >>>不同。 (这就是为什么我们在Java中使用泛型。例如,List<String>List<Object>不同。你不能将List<String>转换为List<Object>

但是,由于你想在某些情况下返回List<Map<>>而在某些其他情况下返回List<Set<>>取决于参数,我建议你将方法serve的返回类型更改为List<? extends Collection>

使用List<? extends Collection>作为返回类型/方法参数意味着此列表可以是Collection的任何子类的List。请查看层次结构以获取更多信息。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.