对NamedParameterJdbcTemplate的引用是不明确的,batchUpdate(String,Map [])和batchUpdate(String,SqlParameterSource [])都匹配

问题描述 投票:1回答:1

也许我缺少一些东西。当我尝试编译实质上是以下内容的代码时,出现以下错误:

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]);

我已经尝试寻找答案,但是所有匹配都说明了(对我而言)歧义已经很清楚的情况。但是这种情况让我感到困惑。

有人有见识吗?

谢谢,戴夫

java generics methods ambiguity
1个回答
1
投票

不完全是一个答案

经过一番调查,发现编译错误是由于:

  1. 方法重载。
  2. 调用重载方法,其中传递参数的方法是直接,而泛型方法是通过Lambda表达式双列运算符]推断返回类型的。
  3. 但是尚未找到原因(相关的JLS)。希望有人能提供更多的解释。

问题演示

下面的代码片段演示了上述创建过程。该代码已使用jdk 1.8.0_151进行了测试。有趣的是,eclipse不会产生编译错误。

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>()));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.