cin
cin

Reputation: 155

Access static method on generic class

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?

Upvotes: 1

Views: 4917

Answers (3)

Peter Lawrey
Peter Lawrey

Reputation: 533930

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.

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

Upvotes: 0

Joachim Sauer
Joachim Sauer

Reputation: 308279

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?

Upvotes: 9

Related Questions