Java 我需要获得一个通用惰性加载程序列表,这些加载程序将实例化其推断类型的实例

Java 我需要获得一个通用惰性加载程序列表,这些加载程序将实例化其推断类型的实例,java,generics,lazy-loading,Java,Generics,Lazy Loading,很抱歉,标题太晦涩了,但这很难解释。一般规则是,我需要一个惰性加载程序,它将为我提供绑定通配符类型的N个实例。我把惰性装载机称为存储单元 import java.util.ArrayList; import java.util.List; public class StorageUnit<T extends MyInterface> implements Storable<T> { private int count; public StorageU

很抱歉,标题太晦涩了,但这很难解释。一般规则是,我需要一个惰性加载程序,它将为我提供绑定通配符类型的N个实例。我把惰性装载机称为存储单元

import java.util.ArrayList;
import java.util.List;

public class StorageUnit<T extends MyInterface> implements Storable<T> {

    private int count;

    public StorageUnit(int count) {
        this.count = count;
    }

    private List<T> storables = new ArrayList<T>();

    public List<T> getInstances(Class<T> c) {
        try {
            if (storables.size() == 0) {
                for (int i = 0; i < count; i++) {
                    storables.add(c.newInstance());
                }
            } else {
                return storables;
            }
        }catch (IllegalAccessException illegalAccessException) {
            illegalAccessException.printStackTrace();
        } catch (InstantiationException instantiationException) {
            instantiationException.printStackTrace();
        }

        return storables;
    }
}
import java.util.ArrayList;
导入java.util.List;
公共类StorageUnit实现可存储{
私人整数计数;
公共存储单元(整数计数){
this.count=计数;
}
private List storables=new ArrayList();
公共列表实例(c类){
试一试{
if(storables.size()==0){
for(int i=0;i
在我的应用程序的其他地方,我有另一个类,它引用了其中几个存储单元。我需要获取存储单元类型的实例,然后我将对该类型执行一些操作

import java.util.ArrayList;
import java.util.List;

public class MyStorageUnitContainer {

    private List<StorageUnit<? extends MyInterface>> storageUnits;

    public MyStorageUnitContainer(List<StorageUnit<? extends MyInterface>> storageUnits) {
        this.storageUnits = storageUnits;
    }

    public List<StorageUnit<? extends MyInterface>> getInstances() {
        List<StorageUnit<? extends MyInterface>> instances = new ArrayList<StorageUnit<? extends MyInterface>>();
        for (StorageUnit<? extends MyInterface> storageUnit : storageUnits) {

            storageUnit.getInstances(/* I can't get the bound wildcard... */);
            // Now loop through those instances and do something with them...

        }
        return instances;
    }
}
import java.util.ArrayList;
导入java.util.List;
公共类MyStorageUnitContainer{

private List对于Java泛型,您无法从类型变量(或者从通配符中获得更少)到实际的类对象

原因是泛型的实现方式:通过类型擦除。这意味着在运行时,泛型类型实际上不再存在,它们被擦除为原始类型。只有编译器检查您是否在正确的位置使用了正确的类型

在您的情况下,
StorageUnit
对象不包含关于此处使用的T的任何信息,如果您没有为它们提供正确类型的类对象。它们也都具有相同的类对象

因此,这里的最佳选择是在构造函数中为StorageUnit对象提供其参数类的class对象,然后是
getInstances()
方法不需要这样做。当然,这只会将问题转移到另一个位置,但这是必要的。

Paulo是正确的,而且(同样根据Paulo的回答),我通常只将一个类对象传递给构造函数来解决这个问题。它允许
getInstances()
方法,使其按照您的意愿显示-即不带参数。在内部,实例保留对泛型类的引用,以便可以对其调用
newInstance()

这段代码用你的例子说明了这一点。我已经测试过了,它执行正常

import java.util.ArrayList;
import java.util.List;

public class Sandbox
{
    static interface MyInterface
    {
    }

    static interface Storable<T>
    {
        List<T> getInstances();
    };

    static abstract class MyStorableImpl implements MyInterface
    {
        @Override
        public String toString()
        {
            return "I'm a " + getClass() + " with hashcode " + hashCode();
        }
    }

    static class MyStorable1 extends MyStorableImpl
    {
    }

    static class MyStorable2 extends MyStorableImpl
    {
    }

    static class StorageUnit<T extends MyInterface> implements Storable<T>
    {
        private final int count;

        private final Class<T> clazz;

        public StorageUnit(Class<T> clazz, int count)
        {
            this.count = count;
            this.clazz = clazz;
        }

        private List<T> storables = new ArrayList<T>();

        public List<T> getInstances()
        {
            try
            {
                if (storables.size() == 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        storables.add(clazz.newInstance());
                    }
                }
                else
                {
                    return storables;
                }
            }
            catch (IllegalAccessException illegalAccessException)
            {
                illegalAccessException.printStackTrace();
            }
            catch (InstantiationException instantiationException)
            {
                instantiationException.printStackTrace();
            }

            return storables;
        }
    }

    static class MyStorageUnitContainer
    {

        private List<StorageUnit<? extends MyInterface>> storageUnits;

        public MyStorageUnitContainer(List<StorageUnit<? extends MyInterface>> storageUnits)
        {
            this.storageUnits = storageUnits;
        }

        public List<MyInterface> getAllInstances()
        {
            List<MyInterface> instances = new ArrayList<MyInterface>();
            for (StorageUnit<? extends MyInterface> storageUnit : storageUnits)
            {
                List<? extends MyInterface> list = storageUnit.getInstances();
                instances.addAll(list);
            }
            return instances;
        }
    }

    public static void main(String[] args)
    {
        StorageUnit<? extends MyInterface> box1 = new StorageUnit<MyStorable1>(MyStorable1.class, 2);
        StorageUnit<? extends MyInterface> box2 = new StorageUnit<MyStorable2>(MyStorable2.class, 3);
        List<StorageUnit<? extends MyInterface>> boxes = new ArrayList<Sandbox.StorageUnit<? extends MyInterface>>();
        boxes.add(box1);
        boxes.add(box2);

        MyStorageUnitContainer container = new MyStorageUnitContainer(boxes);
        List<MyInterface> allInstances = container.getAllInstances();
        for (MyInterface myInterface : allInstances)
        {
            System.out.println(myInterface.toString());
        }
    }

}
import java.util.ArrayList;
导入java.util.List;
公共类沙箱
{
静态接口MyInterface
{
}
静态接口可存储
{
列出getInstances();
};
静态抽象类MyStorableImpl实现MyInterface
{
@凌驾
公共字符串toString()
{
使用hashcode“+hashcode()”返回“我是一个”+getClass()+”;
}
}
静态类MyStorable1扩展了MyStorableImpl
{
}
静态类MyStorable2扩展了MyStorableImpl
{
}
静态类StorageUnit实现可存储
{
私人最终整数计数;
私人期末班;
公共存储单元(类别分类,整数计数)
{
this.count=计数;
this.clazz=clazz;
}
private List storables=new ArrayList();
公共列表getInstances()
{
尝试
{
if(storables.size()==0)
{
for(int i=0;iprivate ListI发现了一些非常类似的东西。关键是通过方法传递泛型类类型,并保留一个字段引用用于实例化。谢谢。