Java 访问泛型类上的静态方法

Java 访问泛型类上的静态方法,java,generics,methods,static,Java,Generics,Methods,Static,我想访问一个类的静态方法,但要以泛型传递该类 我已经做了以下工作: class Base{ public static String getStaticName(){ return "Base"; } } class Child extends Base{ public static String getStaticName(){ return "Child"; } } class StaticAccessor{ public static <T

我想访问一个类的静态方法,但要以泛型传递该类

我已经做了以下工作:

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"

这将返回Base,但我希望它是一个没有反射的建议?

如果没有反射,您不能这样做,因为类型t在运行时被删除,这意味着它将被减少到其下限,即Base

但是,由于您确实有权访问类,因此可以使用反射进行访问:

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

请注意,我认为这些代码是代码嗅觉,而且它非常脆弱。你能告诉我们你为什么需要它吗?

你不能在没有反射的情况下这样做,因为类型t在运行时被擦除,这意味着它将被减少到它的下限,即基本值

但是,由于您确实有权访问类,因此可以使用反射进行访问:

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

请注意,我认为这些代码是代码嗅觉,而且它非常脆弱。您能告诉我们为什么需要它吗?

如果您可以在静态访问器中传递对象实例而不是类,那么有一个简单而优雅的解决方案:

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

    }

}

如果您可以在静态访问器中传递对象实例而不是类,那么有一个简单而优雅的解决方案:

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

    }

}

我不相信你能不经思考就做到这一点


看起来您应该做的不是使用静态方法。您正在使用继承,但静态方法不遵循继承规则。

我不相信您可以在没有反射的情况下做到这一点


看起来您应该做的不是使用静态方法。您正在使用继承,但静态方法不遵循继承规则。

Simpler:return clazz.getSimpleName@内森:是的,如果实施过程总是这样的话。对。只有当getStaticName方法的目的是返回类的简单名称或二进制/规范名称时,我的建议才有效。@JoachimSuer您能更好地解释一下吗?…类型T在运行时被删除。更简单的是:返回clazz.getSimpleName@内森:是的,如果实施过程总是这样的话。对。只有当getStaticName方法的目的是返回类的简单名称或二进制/规范名称时,我的建议才起作用。@JoachimSuer您能解释得更清楚些吗?T类型在运行时被删除。是的,这只是使用多态性来获取名称。最初的示例似乎暗示它应该在没有任何对象实例的情况下工作,并且只针对类工作。我想在本例中,您可以对对象实例本身调用getName方法。@planetjones不,您不能对实例本身调用getStaticName,因为它在两种情况下都只返回'Base'。哦,对不起,我的意思是对对象调用方法,即myOverridable可以直接对b或c调用。是的,这只是使用多态性来获取名称。最初的示例似乎暗示它应该在没有任何对象实例的情况下工作,并且只针对类工作。我想在本例中,您可以对对象实例本身调用getName方法。@planetjones不,您不能对实例本身调用getStaticName,因为在这两种情况下它只返回“Base”。哦,对不起,我的意思是对对象调用该方法,即myOverridable可以直接对b或c调用。