简体   繁体   English

Java(14 及以上)instanceof 转换为 generics(例如 List<string> )</string>

[英]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.

相关问题 具有可选多个边界的泛型,例如List <? extends Integer OR String> - Generics with optional multiple bounds, e.g. List<? extends Integer OR String> 创建包含两个项目的列表,例如列表<String, Integer> - Create List with two items e.g. List<String, Integer> 一个用于压缩(例如LZW)字符串的Java库 - A Java library to compress (e.g. LZW) a string Java泛型:即使已通过instanceof进行检查,也未选中地将其投射到泛型List中 - Java Generics: Unchecked cast in generic List even though already checked with instanceof 如何在 NetBeans IDE 14 中选择 Java Profile(例如 Compact 1、Compact 2、Full JRE)? - How to select Java Profile (e.g. Compact 1, Compact 2, Full JRE) in NetBeans IDE 14? Java:Instanceof 和泛型 - Java: Instanceof and Generics 泛型和instanceof - java - Generics and instanceof - java Java泛型和instanceof关键字 - Java generics and the instanceof keyword 用于泛型类型的Java转换“.class”-operator,例如列表,到“Class <List <?>>”和“Class <List <Integer >>” - Java casting “.class”-operator used on a generic type, e.g. List, to “Class<List<?>>” and to “Class<List<Integer>>” 可以为标准类提供定制的Jackson序列化程序吗? (例如列表 <List<String> &gt;) - Can there be a custom Jackson serializer for a standard class? (e.g. List<List<String>>)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM