动态初始化对象

时间:2015-03-21 21:46:31

标签: java object

以下代码是简化版。 WriteRead是实现IAction接口的类。

IAction newAction;
if (userInput.equalsIgnoreCase("WRITE")){
    newAction = new Write();
}
else if (userInput.equalsIgnoreCase("READ")){
    newAction = new Read();
}
...

如果我有许多行动要实施,那么我将不得不经历太多的if语句。所以问题是,是否有办法自动创建每个类而不通过所有这些if语句?

4 个答案:

答案 0 :(得分:2)

我取决于你的意思"自动"。计算机会自动执行操作,但不会在某人编程自动执行某些操作之前执你可能意味着“不那么累赘”#34;这是一种使用Java 8功能的方法。

// Make a Map that tells what word should be coupled to what action
Map<String, Supplier<IAction>> actionMapping = new HashMap<>();
actionMapping.put("WRITE", Write::new);
actionMapping.put("READ", Read::new);

// When you get user input, simply lookup the supplier
// in the map and call get() on it
IAction action = actionMapping.get(userInput.toUpperCase()).get();

如果您不使用Java 8,则可以使用略有不同(但相似)的方法:

// Map that tells what word should be coupled to what action
Map<String, Class<? extends IAction>> actionMapping = new HashMap<>();
actionMapping.put("WRITE", Write.class);
actionMapping.put("READ", Read.class);

// Lookup the action class for the input and instantiate it
IAction action = actionMapping.get(userInput.toUpperCase()).newInstance();

答案 1 :(得分:1)

是的,它可能。首先创建一个Object。然后检查Classname是否存在以确保userinput是有效类,然后创建动态类。之后将其分配给您的对象。

Object newAction = null;

 try {
  Class<?> clazz =  Class.forName( "your.fqdn.class."+userInput );
  Constructor<?> ctor = clazz.getConstructor(String.class);
  newAction = ctor.newInstance(new Object[] { ctorArgument });
  newAction = new your.fqdn.class."+userInput;
 } catch( ClassNotFoundException e ) {
   // catch an error if the class for the object does not exists.
}

您可以稍后使用

检查课程
if (newAction instanceOf MyClass) { } 
else if (newAction instanceOf Anotherclass) {}

但要小心。这是出于安全原因不推荐的。您应该在执行此操作之前验证输入!

答案 2 :(得分:1)

您可以创建枚举。

public enum Action implements IAction{
    READ,WRITE;
}

并在一行中使用它。

IAction action = Action.valueOf(userInput.toUpperCase());

答案 3 :(得分:0)

您可以使用枚举并为每个枚举常量实现接口。以下是实施Consumer<String>的示例:

public enum Action implements java.util.function.Consumer<String> {
    READ {
        @Override
        public void accept(String t) {
            System.out.println("Read: "+t);
        }
    },
    WRITE {
        @Override
        public void accept(String t) {
            System.out.println("Write: "+t);
        }
    };
}

你可以像这样使用它:

Consumer<String> c = Action.valueOf("READ");
c.accept("Greetings!");
c = Action.valueOf("WRITE");
c.accept("Hello World!");

这将打印

 
Read: Greetings!
Write: Hello World!

无论大小写如何,您都可以使用String.toUpperCase()获得正确的常量。