bennyl
bennyl

Reputation: 2956

Java: get the called class name from static method

I have two classes defined like this:

class A {
    public static String getName(){
        Class c = getCalledClass();
        return c.getSimpleName();
    }
}

class B extends A {
    //no methods are defined here!
}

I want to know if it is possible to compose the static method getCalledClass() such that calling A.getName() will return A and B.getName() will return B?

Thanks.

Upvotes: 5

Views: 5604

Answers (4)

allprog
allprog

Reputation: 16790

The stack trace will contain only the name of the class that that static method is defined on. Even if you call B.method(), you'll see A.method() in the stack trace. Using the static scheme you cannot extract reliably the info you want.

If you use non-static methods then this will be the instance of the type you are looking for.

public String getName() {
  return this.class.getSimpleName();
}

Upvotes: 0

Pete Kirkham
Pete Kirkham

Reputation: 49331

When the javac compiler finds a call to B.getName(), it resolves it there-and-then to A.getName() and puts a static call to A.getName() in the byte code.

There does not exist any mechanism in java which can deduce the form used in the source code from the byte code.

If you want B.getName() to be a different method to A.getName(), you have to define a method called getName() in B. Since in that method the called class will always be 'B', there's no need to mess around with the stack trace or other mechanisms. However, generally if you think it matters what was before the dot, there's probably a better object oriented design for you to use instead.

Upvotes: 0

Andrzej Doyle
Andrzej Doyle

Reputation: 103847

This is not possible, at least not in the general sense that you've asked.

There is no method B.getName(). While you can type that in code, it will be compiled to identical bytecode to A.getName() (and I think you get a compiler warning too).

Thus at runtime, there is no way to tell how someone referenced the static method - just as there's no way to tell what local variable names a caller is using.

Upvotes: 7

Krishan Babbar
Krishan Babbar

Reputation: 798

I don't know if you can remove static or not as per your requirement. If you can remove static and use polymorphism then you can get what you want. Below is the code example I tested.

class A {
    public String getName(){
        Class c = this.getCalledClass();
        return c.getSimpleName();
    }

    Class getCalledClass() {        
        return A.class;
    }
}

class B extends A {
    Class getCalledClass() {
        return B.class;
    }
}

class TestApplication {
    public static void main(String[] args) {
        A objA = new A();
        System.out.println(objA.getName());

        A objB = new B();
        System.out.println(objB.getName());
    }
}

Upvotes: 0

Related Questions