Ссылка на NamedParameterJdbcTemplate неоднозначна, оба batchUpdate (String, Map []) и batchUpdate (String, SqlParameterSource []) совпадают - PullRequest
1 голос
/ 31 марта 2020

Может быть, я что-то упустил. Я получаю следующую ошибку, когда пытаюсь скомпилировать код, по сути следующий:

namedParameterJdbcTemplate.batchUpdate(SQL,
     values.stream().map(val->new MapBuilder<String,Object>()
                            .put("param1",val.getSomeProperty())
                            .put("param2",val.getSomeOtherProperty())
                            .build())
                    .toArray(Map[]::new);

Почему-то это неоднозначно между batchUpdate (String, Map []) и batchUpdate (String, SqlParameterSource []).

SqlParamterSource не реализует Map. Так где же путаница? Даже инкрементный компилятор IntelliJ, похоже, не имеет проблем с кодом. Только когда я пытаюсь скомпилировать код из maven или запустить код, он помечает его как ошибку.

Я могу обойти эту проблему, изменив код следующим образом:

namedParameterJdbcTemplate.batchUpdate(SQL,
     values.stream().map(val->new MapBuilder<String,Object>()
                            .put("param1",val.getSomeProperty())
                            .put("param2",val.getSomeOtherProperty())
                            .build())
                    .collect(Collectors.toList())
                    .toArray(new Map[0]);

Я пытался найти ответ, но все хиты только объясняют сценарий ios, где неоднозначность уже ясна (для меня). Однако этот сценарий меня озадачивает.

У кого-нибудь есть понимание?

Спасибо, Дейв

1 Ответ

1 голос
/ 02 апреля 2020

Не совсем ответ

После некоторого исследования ошибка компиляции возникает из-за:

  1. Перегрузка метода.
  2. Вызов метода перегрузки при передаче параметра напрямую из метода generi c, в котором тип возвращаемого значения определяется лямбда-выражением или оператором с двумя столбцами .

Однако причина (связанная с JLS) пока не найдена. Надеюсь, что кто-то может дать более подробное объяснение.

Демонстрация проблемы

Следующий фрагмент кода демонстрирует вышеуказанное основание. Код протестирован с jdk 1.8.0_151. Интересно, что затмение не дает ошибки компиляции.

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntFunction;

public class AmbitguousMethodTest {
    private <A> A inferByFunctionalInterface(IntFunction<A> d) {
        return null;
    }

    private <A> A inferByArray(A[] a) {
        return null;
    }

    private <A> A inferByOutside() {
        return null;
    }

    private <A> A inferByList(List<A> d) {
        return null;
    }

    private void overloadMethod(BigDecimal a) {
    }

    private void overloadMethod(Integer a) {
    }

    public static void main(String[] args) {
        AmbitguousMethodTest test = new AmbitguousMethodTest();
        testOverloading(test);
    }

    private static void testOverloading(AmbitguousMethodTest test) {
        // Compilation failure reference to overloadMethod is ambiguous
        // By double colon operator
        test.overloadMethod(test.inferByFunctionalInterface(BigDecimal::new));
        // By Lambda expression
        test.overloadMethod(test.inferByFunctionalInterface(i->new BigDecimal(i)));

        // Compile
        // By explicit functional interface
        test.overloadMethod(test.inferByFunctionalInterface(new IntFunction<BigDecimal>() {
            @Override
            public BigDecimal apply(int value) {
                return new BigDecimal(1);
            }
        }));
        test.overloadMethod(test.inferByArray(new BigDecimal[0]));
        test.overloadMethod(test.<BigDecimal>inferByOutside());
        test.overloadMethod(test.inferByList(new ArrayList<BigDecimal>()));
    }
}
...