5

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.

4
  • 3
    It's simpler and faster to pass the calling class as argument Commented Jul 5, 2013 at 11:27
  • Simpler to me - sure, but B.getName(B.class) is less intuitive than B.getName() - if there is no other solution this is what I will do eventually.. Commented Jul 5, 2013 at 11:31
  • In what cases is the called class going to be different? Like if you do B.getName() the called class is B and why do we need to pass that data? Commented Jul 5, 2013 at 11:33
  • Mohamed, no - the called class will be A because those are static methods.. Commented Jul 5, 2013 at 11:34

4 Answers 4

7

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Testing the compiled code - you are right.. well i guess i will have to request the class as parameter.. Thanks.
0

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

Comments

0

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.