I do not believe it is possible to get the name of the base class via reflection when this class is static. You will need to have a direct reference to the class you want to know the name of. This is because in java, when the signatures of the base and drift methods collide, the derivative does not override the method, something called Hide (see an example here).
According to the object-oriented paradigm, it is necessary to have an instance for the overload to occur. In this case, we have static methods, that belong to the class and not to an instance. These methods are solved at compile time and not dynamically (at runtime), as with instance methods. So the polymorphism that we’re used to doesn’t exist in the static context.
Taking into account your example, if we do:
class A {
public static String getNome(){
return A.class.getSimpleName();
}
}
class B extends A {
}
System.out.println(A.getNome()); // vai mostra "A"
System.out.println(B.getNome()); // vai mostrar "A"
A change in this example to come close to what we want:
class A {
public static String getNome(){
return A.class.getSimpleName();
}
}
class B extends A {
public static String getNome(){
return B.class.getSimpleName();
}
}
System.out.println(A.getNome()); // vai mostra "A"
System.out.println(B.getNome()); // vai mostrar "B"
So far so good, is the expected behavior. However, when you do not use a direct reference to the B
, the problem happens again.
// mas o problema persiste quando não se utiliza um referência direta para o `B`
A x = new B();
System.out.println(x.getNome()); // vai mostrar "A"
What if we tried to analyze the stack trace
When analyzed the stack trace of the calls, there is no call to class B, when there is no direct reference and "overload" of the method getNome()
, see:
class A {
public static String getNome(){
String out = "";
for (StackTraceElement var : Thread.currentThread().getStackTrace()){
out += var.getClassName() + "->";
}
out += ".";
return out;
}
}
class B extends A {
}
System.out.println(B.getNome());
// vai mostrar: java.lang.Thread->A->HelloWorld->.
Even with the reference to B
, there is no record in the stack trace. The same goes for:
System.out.println(A.getNome());
// vai mostrar: java.lang.Thread->A->HelloWorld->.
and even "overloading" the method in B
, the expected behaviour does not occur:
class B extends A {
// Agora "sobrecarregando" o método getNome()
public static String getNome(){
return A.getNome();
}
}
System.out.println(B.getNome());
// vai mostrar: java.lang.Thread->A->HelloWorld->.
To paraphrase mathematicians: soon, it is "demonstrated", that it is not possible to obtain the name of the class "caller" using polymorph and reflection without a direct reference to the class "caller".
In this case, having a direct reference to the "calling" class and implementing all this paraphernalia is absurd! If you have the reference of what you want to know the name use B.class.getSimpleName()
or A.class.getSimpleName()
. If you already have everything at compile time, you don’t need to solve at runtime (dynamically) :)
As far as I know, this is not possible. Both static and instance methods are inherited by subclasses, but your behavior is somewhat different. In my mind, though JVM invokes methods differently in bytecode (P.S. I used
getClass2
not to give error), since the same is dispatched (dispatched) I believe that the information about the original call is lost. But I may be wrong, it is good to wait for the answer from someone who understands the subject better.– mgibsonbr