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?

+3


source to share


3 answers


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.

+7


source


Zeroing out the Java spec :

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("");

      

+2


source


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("...","..."));

      

0


source







All Articles