访问泛型类的静态方法

发布于 2024-11-05 13:13:30 字数 473 浏览 0 评论 0原文

我想访问类上的静态方法,但让该类传入泛型。

我已经做了以下操作:

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”,但我想要的是“Child”,任何人都可以提出没有反思的建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

痴情 2024-11-12 13:13:30

如果没有反射,您就无法做到这一点,因为类型 T 在运行时会被擦除(这意味着它将减少到其下限,即 Base)。

由于您确实可以访问Class,因此您可以通过反射来做到这一点,但是:

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

请注意,我认为此类代码是代码味道,并且它是相当脆弱。您能告诉我们为什么您需要它吗?

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?

蓝色星空 2024-11-12 13:13:30

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

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

    }

}

输出为:

Base
Child

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
半世晨晓 2024-11-12 13:13:30

我不相信你不经过反思就能做到这一点。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文