Java - 通用静态方法

时间:2013-04-18 09:52:21

标签: java generics static-methods

我一直试图了解是否有可能创建一个基于返回类推断泛型类型的方法,并调用该泛型类型的静态方法。

即。下面我创建了两个类,它们都实现了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;
    }

}

SubclassA

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时出现以下错误:

线程“main”中的异常java.lang.ClassCastException:不能将ParentClass强制转换为SubclassA     在Wrapper.main(Wrapper.java:20)

我可以用Java做到吗?

3 个答案:

答案 0 :(得分:2)

静态方法不会被覆盖。此static方法属于Class

答案 1 :(得分:1)

不,你不能这样做。要使其工作,您可以传递Class对象:

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

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

答案 2 :(得分:1)

您的方法不正确,Java中没有静态Inheritance的概念,因为继承始终位于对象级别的上下文中。只有具有适当访问修饰符的子类才能继承成员方法(非静态)。

更新: 此外,在您的场景中,工厂模式似乎比调整泛型以获取/构造特定的类对象更合适。