- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是场景:
public static <T> List<T> isTriggeredByBlackList(Map<String, T> params, Class<T> clz) {
System.out.println(clz.getName());
return null;
}
我想要的是通过 String
或List<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
本身)被接受。
所以当方法 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
)的引用!
为什么我们不能传递像 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/
我是一名优秀的程序员,十分优秀!