将 类 存储在一个 Map 中,以便它们可以被实例化
Store classes in a Map so that they can be instantiated
我希望能够基于 HashMap
个条目创建 classes 的实例。
例如这就是我想写下的内容:
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
名称与 classes 相关联。
用户可以使用 "name".
创建 class 的实例
我想尝试:将名称映射到 classes(我不知道如何在映射中存储 classes),然后从映射中获取项目匹配 "name" 然后实例化它。
那不行。
如何将 class 与 String
名称相关联并使用我提供的 'name' 实例化这些 class?
您可以使用 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. For one- and two-argument constructors, you can use Function
and 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");
如果您的构造函数采用不同数量的参数,那么您就不走运了。
我强烈建议在 中使用 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);
注意:这里使用Java10.
您是要存储 类 并按需创建新实例,还是存储实例并仅使用它们?
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");
}
}
我希望能够基于 HashMap
个条目创建 classes 的实例。
例如这就是我想写下的内容:
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
名称与 classes 相关联。
用户可以使用 "name".
创建 class 的实例我想尝试:将名称映射到 classes(我不知道如何在映射中存储 classes),然后从映射中获取项目匹配 "name" 然后实例化它。
那不行。
如何将 class 与 String
名称相关联并使用我提供的 'name' 实例化这些 class?
您可以使用 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. For one- and two-argument constructors, you can use Function
and 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");
如果您的构造函数采用不同数量的参数,那么您就不走运了。
我强烈建议在 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);
注意:这里使用Java10.
您是要存储 类 并按需创建新实例,还是存储实例并仅使用它们?
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");
}
}