我希望能够基于HashMap
条目创建类的实例。
E.g。这就是我尝试写下我的头脑:
public class One implements Interface {
public void sayName() {
System.out.println("One");
}
}
public class Two implements Interface {
public void sayName() {
System.out.println("Two");
}
}
Map<String, Interface> associations = new HashMap<String, Interface>();
associations.put("first", One);
associations.put("second", Two);
Interface instance = new associations.get("first")();
instance.sayName(); // outputs "One"
但我强烈怀疑这在Java中不起作用。
我的情况:我想创建一种将String
名称与类关联的方法。
用户可以使用&#34; name&#34;。
创建类的实例我想尝试:为课程制作名称地图(我不知道如何在地图中存储课程),并从地图中获取匹配&#34; name&#34;然后实例化它。
那不会奏效。
如何将类与String
名称关联,并使用&#39; name&#39;来实例化这些类。我给了它吗?
答案 0 :(得分:6)
您可以使用Supplier
功能界面和默认构造函数的方法引用:
Map<String, Supplier<Interface>> associations = new HashMap<>();
associations.put("first", One::new);
associations.put("second", Two::new);
要实例化新对象,请致电Supplier.get
:
Interface foo = associations.get("first").get();
如果你的构造函数需要参数,那么你需要使用另一个functional interface。对于单参数和双参数构造函数,您可以分别使用Function
和BiFunction
。还有更多,您需要定义自己的功能界面。假设构造函数都接受一个字符串,你可以这样做:
class One implements Interface
{
One(String foo){ }
public void sayName() {
System.out.println("One");
}
}
Map<String, Function<String, Interface>> associations = new HashMap<>();
associations.put("first", One::new);
然后使用Function.apply
获取实例:
Interface a = associations.get("first").apply("some string");
如果你的构造者使用不同数量的参数,那么你就不幸了。
答案 1 :(得分:3)
我强烈建议Michael's answer使用Supplier
。或者,您应该能够使用以下内容:
var associations = Map.of("first", One.class, "second", Two.class);
var foo = associations.get("first").getConstructor().newInstance();
如果构造函数需要参数,只需将类传递给getConstructor
,将值传递给newInstance
。例如,如果Two
在其构造函数中使用int
:
var foo = associations.get("two").getConstructor(int.class).newInstance(5);
注意:这使用Java 10。
答案 2 :(得分:0)
您是想存储类并按需创建新实例,还是存储实例并只使用它们?
public class ClassInHashMap {
public static void main(String[] args) {
Map<String,Class<? extends SomeInterface>> associations = new HashMap<String,Class<? extends SomeInterface>>();
associations.put("first", One.class);
associations.put("second", Two.class);
try {
Class<? extends SomeInterface> someCls = associations.get("first");
SomeInterface instance = someCls.getDeclaredConstructor().newInstance();
instance.sayName(); // outputs "One"
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
interface SomeInterface {
public void sayName();
}
class One implements SomeInterface {
public void sayName() {
System.out.println("One");
}
}
class Two implements SomeInterface {
public void sayName() {
System.out.println("Two");
}
}