Как динамически определить фактический тип литерала типа Object - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть HashMap с некоторыми значениями.Я хочу выполнить итерацию по каждому значению на карте и вызвать метод myFun() для каждого значения.

myFun() - перегруженный метод принимает два аргумента: один является строкой, а другой может иметь тип Integer, десятичный, 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() не должно выдавать ошибку несоответствия типов.

Actual: Следующая ошибка компиляции:прибытие: метод myFun (String, Value) в типе Node не применим для аргументов (String, capture # 3-of?)

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Это не может работать.

Компилятор решает во время компиляции, какой перегруженный метод выбрать.

Вы не можете "отложить" это до времени выполнения.

Единственные способы заставить эту работу:

  • использовать instanceof и статические приведения для всех различных случаев
  • попытаться разработать решениеэто работает с использованием перезаписи, как это происходит во время выполнения (но это может потребовать совершенно другой дизайн)
0 голосов
/ 24 декабря 2018

Чтобы использовать 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...