Which decides if a static or object method should be called
Just a generic request that was invoked by someone accidentally passing a variable of one class, a name that matched the other class, where both methods had the same name, one of which was static.
Considering 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 one
public class B {
public String dothis(String string){
return "Object";
}
}
Does this mean that after an instance of an object, the object will always be called and not a static method?
System.out.println(A.dothis("..."));//outputs Class
B A = new B();
System.out.println(A.dothis("..."));//outputs Object
Nb after instantiation it seems 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 will not compile complaints about the wrong tree type,
Edit: Added a custom exception: -
java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: <any>
at testbed.....
... this means that the compiler decides efficiently which method to call, so the difference in the javac version can behave differently.
What's going on here, and if it's guaranteed, can it be used to obfuscate it in some way, or will decompilation remove the name collision?
source to share
Thereafter:
B A = new B();
... the identifier A
refers to a variable, not a class.
To avoid problems, just don't do it ...
What's going on here, and if it's guaranteed, can it be used to obfuscate it in some way, or will decompilation remove the name collision?
It totally depends on the decompiler. If he's smart enough to recognize the problem, he can rename the local variable to one that doesn't collide.
source to share
A simple name can occur in contexts where it could potentially be interpreted as a variable, type, or package name. In these situations, the rules in section 6.5 specify that the variable will be selected in preference for the type and that the type will be selected in preference for the package. Thus, it is sometimes impossible to refer to a visible type or package declaration through its simple name. We say that such a declaration is hidden.
In your example, A is referring to a variable, not a class. If class A is inside a package, you can still access the static method using:
com.apackage.A.doThis("");
source to share
In your code BA = new B () is an object local variable for class B, class A is hidden from that.
Two options:
Option 1: Use package name (namespace name)
B A = new B();
System.out.println(A.dothis("..."));
System.out.println(Pack1.A.dothis("...","..."));//Class defined in Pack1 package .
Option1: rename a variable
B Renamobj = new B();
System.out.println(A.dothis("..."));
System.out.println(A.dothis("...","..."));
source to share