如何动态确定对象类型文字的实际类型

时间:2018-12-24 12:35:23

标签: java casting

我有一个带有某些值的HashMap。我想遍历映射中的每个值,并为每个值调用方法myFun()

myFun()是一个重载方法,带有两个参数:一个是String,另一个可以是Integer,Decimal,Float,String,String [],Value,Value []等类型:

    Map<String, Object> NodesFound = new HashMap<>();
    String[] children = {"child1","child2","child3","child4"};
    NodesFound.put("String", "Hi its a string");
    NodesFound.put("Number", 1);
    NodesFound.put("children", children);
    Set<String> nodeLabels = NodesFound.keySet();
    for (String label : nodeLabels) {
        Object value = NodesFound.get(label);
        Class<?> theClass = value.getClass();
        myFun("myVal", theClass.cast(value))
    }

预期:myFun()不应出现类型不匹配错误。

实际: 出现以下编译错误: 类型为Node的方法myFun(String,Value)不适用于参数(字符串,      捕获#3-之?)

2 个答案:

答案 0 :(得分:1)

要使用cast,您需要使用非通配符类型参数(例如,theClass)声明Class<String>变量,否则将无法执行此操作指代各种基础类型的类。

这很丑陋,但我认为您不能在这里避免使用instanceof,这可能意味着值得一提,为什么您在同一张地图中拥有各种不同的类型。

但是,如果您要这样做,那么:

if (value instanceof Integer) {
    myFun("myVal", (Integer)value);
} else if (value instanceof String) {
    myFun("myVal", (String)value);
} else if (value instanceof ...) {
    // ...
} else {
    throw new AppropriateException();
}

不过,类似的链条建议您重新思考NodesFound

答案 1 :(得分:0)

这行不通。

编译器在编译时决定选择哪种重载方法。

您不能将其“推迟”到运行时。

完成这项工作的唯一方法:

    在所有不同情况下
  • 使用 instanceof 和静态强制转换
  • 尝试设计一种可以在运行时使用覆盖的解决方案(但这可能需要完全不同的设计)