从 int 映射到 class
Map from int to class
我想根据用户输入创建不同 class 的对象,即用户会告诉要创建哪个 class 的对象。我有这样的东西:
launcher.addProcessor((Processor) new SerializableFieldProcessor(projectKey));
现在我有其他处理器并希望用户提供一个整数输入,并根据该输入创建相应处理器的对象。一种直接的方法是使用 switch case,但稍后我将拥有超过 50 或 100 个独立的处理器。有没有办法用地图或类似的东西来做到这一点?像这样:
Map<int,Processor> mymap;
//initialize mymap;
int x= user_input;
launcher.addProcessor((Processor) new mymap[x]);
public class Foo { }
public class Bar { }
private Object userChosenClass(Int userInput) {
if (userInput == 0) {
return new Foo();
} else if (userInput == 1) {
return new Bar();
} else {
return null;
}
}
或者,您可以拥有 Int 的映射 -> 类,然后查询该映射以获得给定输入 Int 对应的 class。例如:
public class UserClassSelector {
private Map<Int, Class> map;
public UserClassSelector() {
map = new Map<Int, Class>();
}
public Void addMapping(Int fromInt, Class toClass) {
map[fromInt] = toClass;
}
public Object instantiateFromMap(Int forInt) {
if (map[forInt] != null) {
return new map[forInt]();
} else {
return null;
}
}
}
谢谢路斯·瑟林。我找到了使用 Java 反射的解决方案。
Map<Integer,String > rule=new HashMap<Integer, String>();
rule.put(1948,"SerializableFieldProcessor");
Class<?> processor = Class.forName(rule.get(1948));
Constructor<?> cons = processor.getConstructor(String.class);
Object object = cons.newInstance(projectKey);
launcher.addProcessor( (Processor)object);
您可能要考虑的另一种解决方案如下:
Map<Integer, Class<? extends Processor>> map = new HashMap<>();
// Integer.valueOf(x) used to prevent autoboxin just a matter of opinion.
map.put( Integer.valueOf( 0 ), MyProcessor.class );
Processor chosen = map.get( userIn ).getConstructor( String.class ).newInstance( projectKey );
launcher.addProcessor(chosen);
基本相同,区别在于返回的对象是Processor
类型,而class确实存在。当您使用 String 和 Class.forName(...)
时,可能会抛出两个额外的异常。首先是 ClassNotFoundException
,如果 Class.forName()
方法没有找到给定名称的 class 将被抛出。第二个额外的异常是 ClassCastException
如果创建的对象不是 Processor
.
的实现或子 class 将被抛出
解释:
我们正在使用一个映射,其中 Integer
作为键,Class<? extends Processor>
作为值。 Class<T>
对象可以被认为是对应的 .class 文件的对象表示(技术上不正确,但为了简单起见,我们假设它是那样的)。 <? extends Processor>
具体是什么意思?这意味着映射将只允许 类 的值,它们是 Processor
的实现或子类型。这样做消除了 ClassCastException
的线程,因为如果我们只能存储扩展 Processor 的 classes,我们只能检索 classes,它可以转换为 Processor
而无需任何问题,甚至是一个话题。
注意:我链接了实例化过程,这在生产环境中通常是个坏主意,但它大大缩短了代码,因此无需进一步解释,因为您在自己的回答中使用了完全相同的方法。
我想根据用户输入创建不同 class 的对象,即用户会告诉要创建哪个 class 的对象。我有这样的东西:
launcher.addProcessor((Processor) new SerializableFieldProcessor(projectKey));
现在我有其他处理器并希望用户提供一个整数输入,并根据该输入创建相应处理器的对象。一种直接的方法是使用 switch case,但稍后我将拥有超过 50 或 100 个独立的处理器。有没有办法用地图或类似的东西来做到这一点?像这样:
Map<int,Processor> mymap;
//initialize mymap;
int x= user_input;
launcher.addProcessor((Processor) new mymap[x]);
public class Foo { }
public class Bar { }
private Object userChosenClass(Int userInput) {
if (userInput == 0) {
return new Foo();
} else if (userInput == 1) {
return new Bar();
} else {
return null;
}
}
或者,您可以拥有 Int 的映射 -> 类,然后查询该映射以获得给定输入 Int 对应的 class。例如:
public class UserClassSelector {
private Map<Int, Class> map;
public UserClassSelector() {
map = new Map<Int, Class>();
}
public Void addMapping(Int fromInt, Class toClass) {
map[fromInt] = toClass;
}
public Object instantiateFromMap(Int forInt) {
if (map[forInt] != null) {
return new map[forInt]();
} else {
return null;
}
}
}
谢谢路斯·瑟林。我找到了使用 Java 反射的解决方案。
Map<Integer,String > rule=new HashMap<Integer, String>();
rule.put(1948,"SerializableFieldProcessor");
Class<?> processor = Class.forName(rule.get(1948));
Constructor<?> cons = processor.getConstructor(String.class);
Object object = cons.newInstance(projectKey);
launcher.addProcessor( (Processor)object);
您可能要考虑的另一种解决方案如下:
Map<Integer, Class<? extends Processor>> map = new HashMap<>();
// Integer.valueOf(x) used to prevent autoboxin just a matter of opinion.
map.put( Integer.valueOf( 0 ), MyProcessor.class );
Processor chosen = map.get( userIn ).getConstructor( String.class ).newInstance( projectKey );
launcher.addProcessor(chosen);
基本相同,区别在于返回的对象是Processor
类型,而class确实存在。当您使用 String 和 Class.forName(...)
时,可能会抛出两个额外的异常。首先是 ClassNotFoundException
,如果 Class.forName()
方法没有找到给定名称的 class 将被抛出。第二个额外的异常是 ClassCastException
如果创建的对象不是 Processor
.
解释:
我们正在使用一个映射,其中 Integer
作为键,Class<? extends Processor>
作为值。 Class<T>
对象可以被认为是对应的 .class 文件的对象表示(技术上不正确,但为了简单起见,我们假设它是那样的)。 <? extends Processor>
具体是什么意思?这意味着映射将只允许 类 的值,它们是 Processor
的实现或子类型。这样做消除了 ClassCastException
的线程,因为如果我们只能存储扩展 Processor 的 classes,我们只能检索 classes,它可以转换为 Processor
而无需任何问题,甚至是一个话题。
注意:我链接了实例化过程,这在生产环境中通常是个坏主意,但它大大缩短了代码,因此无需进一步解释,因为您在自己的回答中使用了完全相同的方法。