如何在Java中初始化一个类,而我想要初始化的类会因变量而异?

ckx4rj1h  于 2023-09-29  发布在  Java
关注(0)|答案(3)|浏览(82)

我正在尝试做一个终端程序,它将根据用户的输入初始化一个类。有没有一种方法可以使用String变量初始化一个特定的类,而不会用if语句使程序变得混乱?这里有一个我想做的例子:
终端:

Which program would you like to run? Please type in lower case.
 - Room designer
 - Etc.

>

代码:

String answer = input.nextLine();
[answer] programToRun = new [answer]();

有没有办法做到这一点?我知道在Python中有一种使用Globals字典的方法,所以我相信有一种方法,只是我还没有找到它。

ddrv8njm

ddrv8njm1#

实现这一点的方法是使用工厂模式

interface Factory<T> {
  T createInstance(String param);
}

public class FactoryManager {
  private Map<String,Factory> factories;
  public void registerFactory(String type, Factory f) ... // add the key/pair to the factories map
  public Object createInstance(String s) ... // match the string to a Factory in the factories Map and call createInstance on it
}

如果你对此有任何疑问请告诉我
--编辑--
范例:

public class Car {
  private make = null;
  public Car() {};
  public Car(String make) {
    this.Car();
    this.make = make;
  }
}

public class CarFactory implements Factory<Car> {
  public Car createInstance(String s) {
    return new Car(s);
  }
}

public class Bus {
  private make = null;
  public Bus() {};
  public Bus(String make) {
    this.Bus();
    this.make = make;
  }
}

public class BusFactory implements Factory<Bus> {
  public Car createInstance(String s) {
    return new Bus(s);
  }
}

public class MyFactoryManager extends FactoryManager {
  public MyFactoryManager() {
//All this actually should be in the base class FactoryManager so it doesn't need to be implemented in each FactoryManager.
    factories = new HashMap<String, Factory>(); 
    public Object createInstance(String s) { // This could be expanded with another parameter to be passed to the factory for object initialization.
      return factories.get(s).createInstance();
    }
  }
}

FactoryManager fm = new MyFactoryManager();
fm.reqisterFactory("car", new CarFactory());
fm.reqisterFactory("bar", new BusFactory());
Object car = fm.createInstance("car");
Object bus = fm.createInstance("bus");
System.out.println("Car is a " + car.getClass());
System.out.println("Bus is a " + bus.getClass());
kb5ga3dv

kb5ga3dv2#

你可以使用下面的代码从一个字符串创建一个类的示例,使用它的无参数构造函数(如果不存在这样的构造函数,则会崩溃):

package plugins;

public class ClassName {
    @Override
    public String toString() {
        return "Works as expected!";
    }
}

public class ClassByNameTest {
    @Test
    void createInstance() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        String className = "plugins.ClassName";
        Object instance = Class.forName(className).getConstructor().newInstance();

        assert a.getClass().getName().equals(className);
        System.out.println(instance.toString());
    }
}

遵循某种约定,例如实现一个公共接口,您可以调用一个入口点方法来动态运行任意行为。
编辑:尽管这在技术上没有问题,但ControlAltDels使用工厂模式的想法是解决这个问题的更好方法,特别是因为它将用户输入与实际类名分离。

g9icjywg

g9icjywg3#

  • ".有没有一种方法可以让我使用一个String变量初始化一个特定的类,而不用用if语句把我的程序搞得一团糟?..."*

您可以使用 reflection framework 通过 String 值示例化一个类。
您需要提供完全限定名。

Class<?> c = Class.forName("java.lang.String");
Object instance = c.getDeclaredConstructor().newInstance();

相关问题