[英]Java (14 and above) instanceof cast to generics (e.g. List<String> )
I'm deserializing JSON payloads using Jackson. I have some fields that can be either Objects or Arrays of Objects.我正在使用 Jackson 反序列化 JSON 有效负载。我有一些字段可以是对象或对象的 Arrays。 So In my Java code I'm declaring
所以在我的 Java 代码中我声明
class Outer{
private Object inner;
}
I know that inner can be either Map<String,String>
or List<Map<String,String>>
我知道 inner 可以是
Map<String,String>
或List<Map<String,String>>
since I need to do some work with this inner object I have to reside to if - instance of因为我需要用这个内部 object 做一些工作,所以我必须驻留在 if - 的实例
if (inner instanceof List){
List<Map<String,String>> innerAsList = (List<Map<String,String>>)inner;
...
}else if (inner instanceof Map){
Map<String,String> innerAsMap = (Map<String,String>)inner;
...
}else{
throw new IllegalArgumentException("List or Map only");
}
Now trying to use the "new" pattern matching for instanceof
fails to compile (I'm using JDK 17 with previews enabled)现在尝试使用
instanceof
的“新”模式匹配无法编译(我使用的是启用了预览的 JDK 17)
if (inner instanceof List<Map<String,String>> innerAsList){
...
}else if (inner instanceof Map<String,String> innerAsMap){
...
}else{
throw new IllegalArgumentException("List or Map only");
}
fails to compile编译失败
'Object' cannot be safely cast to 'List<String>'
Using wildcard cast compiles使用通配符编译
if (inner instanceof List<?> innerAsList){
...
}else if (inner instanceof Map<?,?> innerAsMap){
...
}else{
throw new IllegalArgumentException("List or Map only");
}
but I then I still need to cast to the correct generic.但是我仍然需要转换为正确的泛型。
Is this solvable somehow?这可以以某种方式解决吗? Is it missing functionality?If so are there plans to have it in a future release?
它是否缺少功能?如果有,是否有计划在未来的版本中使用它?
instanceof is runtime type checking but generics uses type erasure at compile time. instanceof 是运行时类型检查,但 generics 在编译时使用类型擦除。 That's why instanceof is not allowed to use for < T > but allowed to use for the raw type List.
这就是为什么 instanceof 不允许用于 < T > 但允许用于原始类型 List 的原因。 You may check out this tutorial about generics cannot use instanceof: https://www.tutorialspoint.com/java_generics/java_generics_no_instanceof.htm
您可以查看本教程关于 generics cannot use instanceof: https://www.tutorialspoint.com/java_generics/java_generics_no_instanceof.htm
Alternatively, there are some solutions I can think of.或者,我可以想到一些解决方案。
Approach 1: Check the type of the first list item.方法 1:检查第一个列表项的类型。
if (inner instanceof List && !((List) inner).isEmpty() && ((List) inner).get(0) instanceof Map) {
// You may continue to check map key and value if necessary.
} else if (inner instanceof Map) {
// You may continue to check map key and value if necessary.
} else {
throw new IllegalArgumentException("List or Map only");
}
Approach 2: Use type casting in try catch block.方法 2:在 try catch 块中使用类型转换。
try {
Map<String, String> map = (Map<String, String>) inner;
Map.Entry<String, String> entry = map.entrySet().iterator().next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " " + value);
} catch (ClassCastException e) {
System.out.println("Object is not Map<String, String>");
}
You can use Approach 2 with Approach 1 to continue to check after instanceof Map.您可以使用方法 2 和方法 1 在 instanceof Map 之后继续检查。
Approach 3: Use a wrapper class for instanceof.方法 3:对 instanceof 使用包装器 class。
class ListWrapper extends ArrayList<Map<String, String>> {
//...
}
This way takes you more efforts to implement CRUD operations.这种方式需要你更多的努力来实现 CRUD 操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.