Java - 泛型静态方法

8

我一直在尝试理解是否可以创建一个方法,它基于返回类推断泛型类型并调用该泛型类型的静态方法。

例如,下面我创建了两个类,它们都实现了getInstances和getAllInstances方法。然后我尝试从一个通用包装器中使用这些方法。似乎无论返回类型如何,始终会运行超类方法。

例如:

public class ParentClass {

    public ParentClass(){}

    public static <T extends ParentClass> T getInstance(){
        return (T) new ParentClass();
    }

    public static <T extends ParentClass> List<T> getAllInstances(){
        ArrayList<ParentClass> parents = new ArrayList<ParentClass>();

        for(int i=0;i<5;i++){
            parents.add(new ParentClass());
        }

        return (List<T>) parents;
    }

}

子类A

public class SubclassA extends ParentClass{

     public SubclassA(){}

    @SuppressWarnings("unchecked")
    public static SubclassA getInstance(){
         return new SubclassA();
    }

    @SuppressWarnings("unchecked")
    public static List<SubclassA> getAllInstances(){
        ArrayList<SubclassA> parents = new ArrayList<SubclassA>();

          for(int i=0;i<5;i++){
             parents.add(new SubclassA());
          }

         return parents;
      }
 }

包装器 - 显示问题

 public class Wrapper {

    public Wrapper(){
        // ... some other stuff
    }

    public <T extends ParentClass> T getInstance(){
        return T.getInstance();
    }

    public <T extends ParentClass> List<T> getAllInstances(){
        return T.getAllInstances();
    }

    public static void main(String... args){
        Wrapper wrapper = new Wrapper();

        SubclassA subclassA = wrapper.getInstance();
        ParentClass parentClass = wrapper.getInstance();

        System.out.println(subclassA.getClass().getName());
        System.out.println(parentClass.getClass().getName());
    }

 }

运行 Wrapper 时出现以下错误:

Exception in thread "main" java.lang.ClassCastException: ParentClass 无法强制转换为 SubclassA     at Wrapper.main(Wrapper.java:20)

我能在Java中实现这个吗?


你在一个类上调用了一个静态方法,它会被执行。为什么它要委托给子类来调用?而且如何确定是哪个子类? - Gab
希望它可以通过从返回类型推断来确定委托给哪个子类。现在我明白了,你不能覆盖静态方法,这很有道理。 - user2294382
3个回答

2

静态方法不会被覆盖。这些静态方法属于级别。


1

不,你不能像这样做。为了使其工作,你可以传递类对象:

public class ParentClassUtils

    public static <T extends ParentClass> T getInstance(Class<T> clazz) {
        return clazz.newInstance();
    }

    public static <T extends ParentClass> List<T> getAllInstances(Class<T> clazz) {
        List<T> list = new ArrayList<T>();
        for (int i = 0; i < 5; i++) {
            list.add(getInstance(clazz));
        }
        return list;
    }
}

此外,在您的示例中,父类和子类中都有等效的静态方法。子类方法不会覆盖父类方法,只是隐藏它们,这几乎肯定不是您想要的。上面的实用程序类方法可以解决这个问题。

1
你的方法是不正确的,在Java中没有静态继承的概念,因为继承总是在对象级别上进行。只有成员方法(非静态)可以通过具有适当访问修饰符的子类继承。
更新: 此外,针对你的情况,工厂模式似乎比调整泛型以获取/构造特定类对象更合适。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接