Skip to content
Advertisement

foo(int, int) is picked over foo(int…)

In this piece of code, why the compiler is not able to reference the method that has varargs argument from static context.

 private static void doSomething(int... nums) {
    System.out.println("1");
}
private void doSomething(int num1, int num2) {
    System.out.println("2");
} 

public static void main(String[] args) {
    doSomething(1,2);
}

JDK 17 is complaining Cannot make a static reference to the non-static method doSomething(int, int) . Is this a bug or another feature I am not aware of.

JDK 8 and JDK 11 dont complain about it!

Advertisement

Answer

The behavior of rejecting the method invocation is correct. Method resolution should find the most specific method first and check for the static modifier afterwards.

But there is a bug in javac from version 7 to 16.

See

JDK-8268474, Method resolution should stop on static error

Javac is not in sync with section §15.12.3 of the JLS 16 specification. In particular, for invocations in static context, javac too early checks whether the method is static, and when it determines it is not static and cannot be called, proceeds to a further phase in method lookup, even though it should report a compile-time error.

This bug has been fixed with JDK 17.

Note that Eclipse’s compiler ECJ does not have this bug, so the example is rejected in Eclipse, regardless of which JDK version you use.

Only invocations using a simple name are affected. When you use ClassName.doSomething(1,2);, all versions will resolve the invocation to doSomething(int num1, int num2) and generate the correct error.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement