1

I'd like to access a static method on a class, but have that class passed in a generic.

I've done the following:

class Base{
  public static String getStaticName(){
    return "Base";
  }
}


class Child extends Base{
  public static String getStaticName(){
    return "Child";
  }
}

class StaticAccessor{
  public static <T extends Base>String getName(Class<T> clazz){
    return T.getStaticName();
  }
}

StaticAccessor.getName() // --> "Base"

This will return "Base" but what i'd like is "Child" anybody a suggestion without reflections?

3 Answers 3

9

You can't do that without reflection, because the type T is erased at runtime (meaning it will be reduced to its lower bound, which is Base).

Since you do have access to a Class<T> you can do it with reflection, however:

return (String) clazz.getMethod("getStaticName").invoke(null);

Note that I'd consider such code to be code smell and that it is pretty fragile. Could you tell us why you need that?

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

4 Comments

Simpler: return clazz.getSimpleName();
@Nathan: yes, if the implementation will always look like that.
correct. My suggestion works only if the intention of the getStaticName() method is to return the simple (or binary/canonical) name of the class.
@joachimSauer could you please explain better "...the type T is erased at runtime".
0

If it is OK for you to pass an object instance rather than Class in your static accessor, then, there is a simple and elegant solution:

public class Test {

    static class Base {
        public static String getStaticName() { return "Base"; }
        public String myOverridable() { return Base.getStaticName(); };
    }

    static class Child extends Base {
        public static String getStaticName() { return "Child"; }
        @Override
        public String myOverridable() { return Child.getStaticName(); };
    }

    static class StaticAccessor {
        public static <T extends Base>String getName(T instance) {
            return instance.myOverridable();
    }

}


    public static void main(String[] args) {

        Base b = new Base();
        Child c = new Child();

        System.out.println(StaticAccessor.getName(b));
        System.out.println(StaticAccessor.getName(c));

    }

}

The output is:

Base
Child

3 Comments

Yep this is just using polymorphism though to get the Name. The original example seemed to imply it should work without any Object instances and work just against the Class. I guess in the example you could just call the getName method on the object instance itself.
@planetjones No, you cannot call getStaticName() on the instance itself, because it would only return 'Base' in both cases.
oh sorry I meant to say call the method against the Object i.e. myOverridable() could be called directly against b or c.
0

I don't believe you can do this without reflection.

It appears you should be doing is not using static methods. You are using inheritance but static methods do not follow inheritance rules.

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.