How do I get the class name in a static context?

3

I want to get the name of the class that called my method

class A {
    public static String getClass(){
       return getCalledClass(); /*Supondo que exista esse metodo*/
    }
}

class B extends A{

}

When I do:


System.out.println(A.getClass()); // deve mostrar "A"
System.out.println(B.getClass()); // deve mostrar "B"

    
asked by anonymous 22.06.2014 / 21:33

2 answers

3

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):

    
23.06.2014 / 01:25
2

Stack. Home

package stack;

public class Principal {
    public static void main(String[] args) {
        //Dinâmico
        A a = new A();
        B b = new B();
        a.getClasse();
        b.getClasse();
        //Estático
        A.getStaticClasse();
        B.getStaticClasse();
    }
}

stack. A

public  class A {
       public void getClasse(){
               System.out.println("classe = " + this.getClass());
       }

       public static void getStaticClasse(){
               System.out.println("classe estatica = " + A.class.getName());
       }
}

stack. B

package stack;

public class B extends A{
    public static void getStaticClasse(){
           System.out.println("class estática= " + B.class.getName());
   }
}

Output:

class = class stack.A
class = class stack.B
static class = stack.A
static class = stack.B

If you want to download the project the same can be found at GitHub

Note that you will have to create such a method in all classes, or the return would still be stack.A .

    
22.06.2014 / 23:36