Reputation: 1651
The following code is a simplified version. The Write
and Read
are classes that implement the IAction
interface.
IAction newAction;
if (userInput.equalsIgnoreCase("WRITE")){
newAction = new Write();
}
else if (userInput.equalsIgnoreCase("READ")){
newAction = new Read();
}
...
If I had many actions to implement then i would have to go through too many if statements. So the question is if there is a way to automatically create each class without getting through all these if statements?
Upvotes: 1
Views: 1254
Reputation: 82461
You can use a enum and implement the interface for each enum constant. Here's an example for implementing 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);
}
};
}
You can use it like this:
Consumer<String> c = Action.valueOf("READ");
c.accept("Greetings!");
c = Action.valueOf("WRITE");
c.accept("Hello World!");
This will print
Read: Greetings!
Write: Hello World!
You can use String.toUpperCase()
get the right constant regardless of upper and lower case.
Upvotes: 0
Reputation: 38633
You can create an enum.
public enum Action implements IAction{
READ,WRITE;
}
And use it in one line like so.
IAction action = Action.valueOf(userInput.toUpperCase());
Upvotes: 1
Reputation: 206896
I depends on what you mean by "automatically". Computers do things automatically, but not before someone programmed to do something automatically. You probably mean "less cumbersome". Here is an approach that uses Java 8 features.
// 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();
If you're not using Java 8, you can use a slightly different (but similar) approach:
// 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();
Upvotes: 2
Reputation: 8106
Yes, its possible. First create an Object. Then check if the Classname exists to make sure that the userinput is a valid class, then create a dynamic class. After that assign it to your Object.
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.
}
You can later check for the class by using
if (newAction instanceOf MyClass) { }
else if (newAction instanceOf Anotherclass) {}
But be carefull. This is for security reasons not recommend. You should validate the input before you do that!
Upvotes: 2