java - 方法参数的泛型类型

标签 java generics generic-list

这是场景:

public static <T> List<T> isTriggeredByBlackList(Map<String, T> params, Class<T> clz)   {
    System.out.println(clz.getName());

    return null;
}

我想要的是通过 StringList<String>到这个方法。

说到String ,它工作得很好:

Map<String, String> map1 = new HashMap<String, String>();
map1.put("11", "22");
isTriggeredByBlackList(map1, String.class);

但是当我试图通过 List<String> ,出错了:

Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> l = new ArrayList<String>();
l.add("11");
l.add("22");
map.put("1", l);
isTriggeredByBlackList(map, List.class);    //compile error!

编译错误如下:

The method isTriggeredByBlackList(Map<String,T>, Class<T>) in the type CommonTest is not applicable for the arguments (Map<String,List<String>>, Class<List>)

我需要的是编写一种适合两者的方法 String类型以及 List<String>类型。

有人可以帮我吗?非常感谢!

最佳答案

更改方法的签名:

public static <T> List<T> isTriggeredByBlackList(Map<String, ? extends T> params, Class<T> clz)

为什么会这样?

表达式? extends T只是意味着任何类型 T 的子类型(当然还有 T 本身)被接受。

What is a wildcard?

所以当方法 isTriggeredByBlackList是这样调用的:

isTriggeredByBlackList(map, List.class);

... T被指定为(原始)List类型,因此第一个参数必须是 Map<String, any-type-that-extends-raw-List> ,对于 Map<String, List<String>> 来说也是如此。 (因为 List<String> 是(原始) List 的子类型)。

<小时/>

但是为什么列表是(原始)列表的子类型?

泛型很棘手,因为多态性不能按预期工作(乍一看)。一个List<String> 不是 List<Object> ,虽然String延伸Object !所以这行不通:

List<Object> objList = new ArrayList<String>(); // compile error

(注意:这是不可能的,但那是另一个故事了)

但是一个List<String> IS-a(原始)List (它是一个 List<?> )。所以这有效:

List rawList = new ArrayList<String>(); // just compiler warning
List<?> unknownList = new ArrayList<String>();

原因是:原始类型仍然支持向后兼容!否则,不支持泛型的旧代码现在无法使用。因此,具体参数化类型的任何实例(例如 ArrayList<String> )都可以分配给其原始类型(例如 ArrayList )或父类(super class)型(例如 List )的引用!

Why are raw types permitted?

为什么我们不能传递像 List<String>.class 这样的东西? ?

因为参数化类型没有精确的运行时类型表示!

Why is there no class literal for concrete parameterized types?

但我想要一个List<List<String>>作为返回值!

这没问题!只需将作业的左侧定义为 List<List<String>> ,剩下的由 java 完成:

List<List<String>> l = isTriggeredByBlackList(map, List.class);
但是!仅当您稍微修改方法声明时,这才有效:

public static <T> List<T> isTriggeredByBlackList(
    Map<String, ? extends T> params, Class<? super T> clz)

(否则您无法传递原始 List.class 作为第二个参数)。

<小时/>

所有这些修改和调整是否有意义取决于您的方法应完成的任务!是不是只读取params ?它如何使用泛型类型参数?在这里使用泛型有什么好处?等等

<小时/>

顺便说一句:以 is... 开头的方法应该返回 boolean值(value)。考虑重命名您的方法! 顺便说一句2.:你的方法的返回类型是 List<T> ,所以如果您指定 T成为List ,您将得到 List<List> 。这是故意的吗?

关于java - 方法参数的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20327206/

相关文章:

java - 如何调用泛型方法?

c# - IList-LINQ进行过滤和排序

c# - 两个列表同步

java - 泛型类型的集合

java - 如何在泛型类中返回 `this`?

arrays - Powershell阵列:何时使用它们;什么时候避免他们和使用它们的问题

java - 为什么方法不能识别指向静态变量的变量?

java - JDialog 大小未渲染

java - android 中的 lang.NumberFormatException

java - Websphere 自由 8.5 : Setting Java classpath