Java 我需要获得一个通用惰性加载程序列表,这些加载程序将实例化其推断类型的实例
很抱歉,标题太晦涩了,但这很难解释。一般规则是,我需要一个惰性加载程序,它将为我提供绑定通配符类型的N个实例。我把惰性装载机称为存储单元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
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;i private ListI发现了一些非常类似的东西。关键是通过方法传递泛型类类型,并保留一个字段引用用于实例化。谢谢。