I do not believe it's 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 that wants to know the name. This happens because in Java, when the signatures of the base and drift methods collide, the derivative does not override the method, something called hide happens (see an example here ).
According to the object-oriented paradigm, there must be an instance for overloading to occur. In this case, we have static methods , which belong to the class and not to an instance. These methods are resolved at compile time and not dynamically (at runtime), as they do with instance methods. Thus, the polymorphism we are accustomed to does not exist in the static context.
Given 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 get close to what we want would be:
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
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"
And if we tried analyzing the stack trace
When analyzing the stack trace of calls, there is no call to class B, when there is no direct reference and "overload" of 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 stack trace . The same thing happens for:
System.out.println(A.getNome());
// vai mostrar: java.lang.Thread->A->HelloWorld->.
and even if you overload the method with B
, the expected behavior does not happen:
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->.
Paraphrasing the mathematician: therefore, it is "demonstrated" that it is not possible to get the name of the "calling" class using polymorphism and reflection without a direct reference to the calling class.
In this case, having a direct reference to class "caller" and implement all this paraphernalia is absurd! If you have the reference you want to know the name use B.class.getSimpleName()
or A.class.getSimpleName()
. If you already have everything at compile time, you do not need to resolve at runtime (dynamically):