What decides whether a static or object method should be called

Just a general query that came about by someone accidentally giving a variable of one class a name that matched another class where both had a method of the same name, one of which was static.

Given the following:

public class A {
    public static String dothis(String string){
        return "Class";
    }

    public static String dothis(String string, String string2){
        return "Class Method 2";
    }
}

and this

public class B {    
    public String dothis(String string){
        return "Object";
    }
}

Is it that the following will always call the object and not the static method once the object is instantiated?

System.out.println(A.dothis("..."));//outputs Class
B A = new B();
System.out.println(A.dothis("..."));//outputs Object

N.b. following instantiation it appears to be impossible to call any static methods in class A, i.e.

B A = new B();
System.out.println(A.dothis("..."));
System.out.println(A.dothis("...","..."));//Won't compile

the above won't compile complaining about an erroneous tree type,

Edit: added specific exception :-

java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: <any>
    at testbed.....

... does this mean the compiler is effectively deciding which method to call, so a difference javac version may behave differently.

What is going on here and if this is guaranteed could it be used for obfuscation in some way, or would decompilation remove the name clash?

Jon Skeet
people
quotationmark

After doing this:

B A = new B();

... the identifier A refers to the variable, not the class.

To avoid that being a problem, just don't do that...

What is going on here and if this is guaranteed could it be used for obfuscation in some way, or would decompilation remove the name clash?

That entirely depends on the decompiler. If it's smart enough to recognize the issue, it could rename the local variable to one that doesn't clash.

people

See more on this question at Stackoverflow