2

I have 2 classes A and B where B extends A. Both class are having a static variable x. There is one static method defined in class A which is accessing x. When I call the method with B from main, is there any way to know the caller of the function? With that caller class name I can use reflection in order to get value of x from class B.

public class Test {
    public static void main(String[] args) throws Exception {
        A a = new A();
        B b = new B();
        b.amthu();
    }
    private static class A {
        public static String x = "static string from A";
        public static void amthu() throws NoSuchFieldException, IllegalAccessException {
            System.out.println(/* what can be the line here?*/);
        }
    }
    private static class B extends A {
        public static String x = "static string from B";
    }
}

I have similar code in python which works fine because of the class method having cls as arguments but static method doesn't have such thing and in Java I am only aware of static methods so can't access value of x from sub-class B.

class A:
    x = "static value of A"

    @classmethod
    def amthu(cls):
        print(getattr(cls, "x", None))


class B(A):
    x = "static value of B"


a = A()
b = B()
b.amthu()
Deep Joshi
  • 482
  • 5
  • 13
  • It worked when method is non static. – Deep Joshi Aug 16 '20 at 14:39
  • *"When I call the method from B"* - but you're not calling the method from B, you're calling it from Test.main? can you clarify what the expected behavior is? – Joni Aug 16 '20 at 14:41
  • 1
    new Throwable().getStackTrace()[0].getClassName() is giving A as classname inside the method. – Deep Joshi Aug 16 '20 at 14:42
  • @Joni, I am calling it form main but calling it with an Object of B. – Deep Joshi Aug 16 '20 at 14:43
  • 1
    You should try to use correct terms. The caller class is `Test`. The object you’re invoking the `static` method on, is irrelevant. The possibility to invoke `static` methods on an object can be seen as a historic design mistake. However, even if you use `A.amthu()` and `B.amthu()` to invoke it, it makes no difference to the invoked method. – Holger Aug 17 '20 at 13:00

2 Answers2

1

There is no way the A.amthu() method can detect it was called using a variable of the type B.

Static methods in Java have fundamental limitations such as this. These limitations are why you don't see static methods used very much in Java. In particular, calling static methods using object instances like b.amthu() is discouraged because it leads to confusion - see also Why isn't calling a static method by way of an instance an error for the Java compiler?

You can get around this by passing the class you expect as a variable to A.amthu:

// call method
A.amthu(B.class);

// method declaration in A
static void amthu(Class<? extends A> klass) { ... }

Or perhaps you can rework your code to avoid using static fields and methods altogether. It's impossible to tell you what that would look like without knowing what you're trying to do here though.

Joni
  • 108,737
  • 14
  • 143
  • 193
0

You can do instanceof check and then print B.x or A.x

If(this instanceof A) System.out.println A.x else System.out.println B.x

s_mstdib
  • 1
  • 1
  • Does this code compile ? Please provide correct example and don't forget add code formatting. Please check - https://meta.stackoverflow.com/questions/251361/how-do-i-format-my-code-blocks – Pankaj Aug 16 '20 at 15:15
  • this pointer can only be accessed in case of non static methods. – Deep Joshi Aug 16 '20 at 15:18
  • Missed that , polymorphism is not applicable for static methods. When you call b.amthu() , amthu() method of Class A is called as it is not defined in B but once inside amthu() it will only reference A’s static variable as static method was invoked on class A by the compiler. – s_mstdib Aug 16 '20 at 17:40