简体   繁体   中英

How to dynamically determine the actual type of a literal of Object type

I have a HashMap with some values. I want to iterate over each value in the map and call a method myFun() for every value.

myFun() is an overloaded method takes two arguments: One is String and other can be of type Integer, Decimal, Float, String, String[], Value, Value[] etc:

    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))
    }

Expected: myFun() should not give Type mismatch error.

Actual: The following compilation error is coming: The method myFun(String, Value) in the type Node is not applicable for the arguments (String, capture#3-of ?)

To use cast , you would need the theClass variable to be declared with a non-wildcard type parameter (eg, Class<String> ), which you can't do if it's going to refer to classes of varying underlying types.

It's ugly, but I don't think you can avoid instanceof here, which probably means it's worth revisiting why you have various different types in the same map.

But if you're going to do that, then:

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();
}

Again, though, chains like that suggest you want to rethink NodesFound .

This can't work.

The compiler decides at compile time which overloaded method to pick.

You can't "postpone" this to runtime.

The only ways to make this work:

  • use instanceof and static casts for all the different cases
  • try to design a solution that works using overwriting, as that happens at runtime (but that might require a completely different design)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM