方法参数的泛型类型

 mobiledu2502923573 发布于 2023-02-13 14:12

这是场景:

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

    return null;
}

我要的是通过其中StringList以这种方法.

说到它String,它的工作正常:

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

但是当我试图通过时List,它出错了:

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

编译错误如下:

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

我需要的是只编写一个适用于String类型和List类型的方法.

任何人都可以帮我吗?非常感谢!

1 个回答
  • 更改方法的签名:

    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类型,因此第一个参数必须是a Map<String, any-type-that-extends-raw-List>,对于Map<String, List<String>>(因为List<String>是(raw)的子类型)是真的List.


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

    泛型是棘手的,因为多态性不能按预期工作(第一眼看见).A List<String> 是-NOT-a List<Object>,虽然String延伸Object!所以这不起作用:

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

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

    但是List<String> IS-a(原始)List(它是-a List<?>).这样可行:

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

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

    为什么允许原始类型?

    为什么我们不能通过类似的东西List<String>.class

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

    为什么没有具体参数化类型的类文字?

    但我希望获得一个List<List<String>>返回值!

    这没问题!只需将赋值的左侧定义为a 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)
    

    (否则你不能将raw List.class作为第二个参数传递).


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


    顺便说一句:开头的方法is...应该返回一个boolean值.考虑重命名您的方法!顺便说一句2:你的方法的返回类型是List<T>,所以万一你指定T是a List,你会得到一个List<List>.这是有意的吗?

    2023-02-13 14:14 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有