BrandenS
BrandenS

Reputation: 641

Dynamically instantiating an object in java

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

Answers (3)

ostrichofevil
ostrichofevil

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:

  • There is no class with the given name.
  • The user says something like "String" instead of "java.lang.String". Class.forName(String s) only works with fully qualified names.
  • The class has no nullary constructor (a constructor that takes no arguments).

Also, as someone mentioned, this is a very insecure and unstable thing to do.

Upvotes: 1

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

user4910279
user4910279

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

Related Questions