'Generic Return Types
Would there be a better way to write this getInput() method instead of checking for every single class that could be passed in?
public Object getInput(String prompt, Class<?> type) {
System.out.print(prompt);
Scanner scn = new Scanner( System.in );
String str = scn.nextLine( );
if(type.equals(Integer.class))
return Integer.parseInt(str);
else if (type.equals(Double.class))
return Double.parseDouble(str);
else if (type.equals(Boolean.class))
return Boolean.parseBoolean(str);
else return type.cast(str);
}
It works enough, but I would like to make it work with mostly all cases without having to add many more else if statements. As well as this, I am required to cast to that type when I take the input and assign it to a variable. Is there a way I could get around this?
Invocation:
int num = (int)menu.getInput("Enter an integer: ", Integer.class);
Solution 1:[1]
There's a few ways you "might" do this, but probably one of the ways which won't have you modifying the "base" input method every time you want a new input type, would be to inject the "parsing" workflow into the method itself.
That is, create a generic interface which defines a "parse" method which can take a String and return value of a specific type and pass that to your input method, for example...
import java.util.Scanner;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Integer result = getInput("Please enter an integer: ", new IntParser());
}
public interface Parsable<T> {
public T parse(String value);
}
public class IntParser implements Parsable<Integer> {
@Override
public Integer parse(String value) {
return Integer.parseInt(value);
}
}
public <T> T getInput(String prompt, Parsable<T> parser) {
System.out.print(prompt);
Scanner scn = new Scanner(System.in);
String str = scn.nextLine();
return parser.parse(str);
}
}
Now, if you didn't want to have to type getInput("Please enter an integer: ", new IntParser()); every time ?, you could create connivence methods to make your life easier, for example...
public int getIntInput(String prompt) {
return getInput(prompt, new IntParser());
}
Now, me, I'd probably create class to encompass it all...
public class InputManager {
public interface Parsable<T> {
public T parse(String value);
}
public class IntParser implements Parsable<Integer> {
@Override
public Integer parse(String value) {
return Integer.parseInt(value);
}
}
protected Scanner scanner;
public InputManager(Scanner scanner) {
this.scanner = scanner;
}
public InputManager() {
this(new Scanner(System.in));
}
public <T> T getInput(String prompt, Parsable<T> parser) {
System.out.print(prompt);
String str = scanner.nextLine();
return parser.parse(str);
}
public int getIntInput(String prompt) {
return getInput(prompt, new IntParser());
}
}
But I am crazy ?
Important - This doesn't deal with error handling. I might, for example, have the Parsable return null when it's unable to parse the result, otherwise you should probably define a ParsingException so that calls are made aware of their responsibilities
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MadProgrammer |
