0

My test code:


class Test1{
    public void a(String a) {
        
    }

    public static void a(String a, Object... objects) {

    }
    public static void b(String a, Object... objects) {

    }

    public static void main(String[] args) {
        Test1.a("");    // call static a(), compile error: Non-static method 'a(java.lang.String)' cannot be referenced from a static context
        Test1.b("");    // it is working.
    }
}

Why did this error occur? Why didn't JDK find static method a() ? how to fix this error?

Guo
  • 1,761
  • 2
  • 22
  • 45

1 Answers1

2

Your call to a() has one String argument.

You have implementations of a() with (i) one String argument, or (ii) one String argument plus zero or more Objects.

Case (i) is a more specific match for the call.

Determining which method a call refers to is described here in the JLS.

How to fix? You need to resolve the ambiguity. You could give the call some sort of dummy argument. My choice, however, would be to not use the same name 'a' for a static and non-static method.

Or else make both the 'a' methods static -- that would satisfy the compiler, but it might make it difficult to use, if a("") and a("", "") have completely unrelated actions. But that of course is always a consideration for overloading names.


But 'why' is it like this? Isn't it obvious that Test1.a(...) is a call on a static member, since it is prefixed with a class name rather than an instance reference?

Perhaps. But consider that within a class, you can call a static method without the class name as a qualifier, and you can call a non-static method without 'this' as a qualifier. That is, a call foo() could refer to either a static method or a non-static method. So in general, resolving an overloaded name must consider both static and non-static possibilities. The case we're looking at is obeying the general rule (even though one might argue that it need not do so - but that's a matter for the language designers).

dangling else
  • 438
  • 2
  • 3