Reputation: 641
I don't know if I have titled this correctly, but, I am looking for a way to instantiate a new object of a subclass based on user input. IE, I want to ask the user what sub class they want to create, and then create it based on that choice. So it may look like
String category = CATEGORIES[Integer.parseInt(scanner.nextLine())];
items.add(new category(myString, myInt));
I am adding these into an ArrayList.
That new keyword seems to only accept an actual class though and not anything else. I have played around with built in Class methods but when i try to put those after the new call it fails. Pretty much anything I put after the new call except the class itself fails.
Is this something that is possible?
Thanks!
Upvotes: 2
Views: 247
Reputation: 734
I wouldn't recommend this, but it is possible with Reflection:
Object thing = Class.forName(category).getConstructor().newInstance();
This gets the class with the name stored in category
, gets its no-argument constructor, and invokes it, storing the resulting Object
in thing
.
A lot can go wrong here; this will only work if none of the following are true:
Class.forName(String s)
only works with fully qualified names.Also, as someone mentioned, this is a very insecure and unstable thing to do.
Upvotes: 1
Reputation: 1968
You are looking for reflection, and Class.forName()
and Class.forName().newInstance()
Look: What is the difference between "Class.forName()" and "Class.forName().newInstance()"?
There is an example.
Look also: Initializing a class with Class.forName() and which have a constructor which takes arguments
Upvotes: 1
Reputation:
Try this
public class Category {}
public class Foo extends Category { public Foo(String s, int i) {}}
public class Bar extends Category { public Bar(String s, int i) {}}
String[] CATEGORIES = { Foo.class.getName(), Bar.class.getName() };
static final Class<?>[] ARGTYPES = { String.class, int.class };
and
List<Category> items = new ArrayList<>();
String category = CATEGORIES[Integer.parseInt(scanner.nextLine())];
items.add((Category)Class.forName(category)
.getConstructor(ARGTYPES)
.newInstance(myString, myInt));
Upvotes: 0