Groovy中Character为键的HashMap不生效,泛型支持是否不完善?
问题原因与解决方法
核心原因
不是Groovy泛型支持不成熟,问题来源于Groovy默认的动态类型特性和字面量默认类型规则:
- Groovy默认作为动态类型语言,运行时会进行泛型擦除,你声明的
Map<Character, Character>仅在开启静态编译校验时生效,默认场景下不会限制map实际存储的键值类型。 - 你使用
[ '}':'{', ')': '(', ']': '[' ]字面量创建map时,单引号包裹的内容在Groovy中默认是String类型,而非Character类型,因此实际存入map的键都是String类型,你传入Character类型参数调用get()方法时,类型不匹配自然返回null。
为什么换成Map<String, String>就能正常运行
当你把map声明为Map<String, String>后,Groovy动态类型机制会自动将你传入的Character类型参数调用toString()转为String,和map中存储的String类型键匹配,因此可以正常拿到返回值。
解决方案
有三种常见的修复方式:
- 显式将map字面量的键值转为Character类型,示例代码:
Map<Character, Character> map = [ (('}') as char) : ('{' as char), ((')') as char) : ('(' as char), ((']') as char) : ('[' as char) ]
- 开启Groovy静态编译校验,在方法或类上添加
@CompileStatic注解,此时Groovy会在编译阶段强制校验泛型类型,你传入String类型的键不符合Character声明会直接编译报错,提前发现类型不匹配问题。 - 保留
Map<String, String>的声明,调用get()时主动将Character参数转为String:
if (c1 == map.get(c as String)){ stack.pop() }
内容的提问来源于stack exchange,提问作者indranil32
相关产品推荐
相关产品推荐

