在java中动态实例化对象

时间:2016-02-09 22:02:02

标签: java class object dynamic

我不知道我是否正确标题,但是,我正在寻找一种基于用户输入实例化子类的新对象的方法。 IE,我想问用户他们想要创建什么子类,然后根据该选择创建它。所以它可能看起来像

 String category = CATEGORIES[Integer.parseInt(scanner.nextLine())];   
 items.add(new category(myString, myInt));

我将这些添加到ArrayList中。

新关键字似乎只接受实际的类而不是其他任何东西。我玩过内置的Class方法,但是当我尝试将它们放在新的调用之后它就失败了。除了班级本身失败之外,几乎我在新电话之后放了什么。

这是可能的吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

您正在寻找反思,以及Class.forName()Class.forName().newInstance()

查找: What is the difference between "Class.forName()" and "Class.forName().newInstance()"?

有一个例子。

看看: Initializing a class with Class.forName() and which have a constructor which takes arguments

答案 1 :(得分:1)

我不推荐这个,但有可能使用Reflection:

Object thing = Class.forName(category).getConstructor().newInstance();

这将获取名称存储在category中的类,获取其无参构造函数,并调用它,将结果Object存储在thing中。

这里可能出现很多问题;这只有在以下情况均不属于的情况下才有效:

  • 没有具有给定名称的课程。
  • 用户说出" String"而不是" java.lang.String"。 Class.forName(String s)仅适用于完全限定名称。
  • 该类没有nullary构造函数(不带参数的构造函数)。

另外,正如有人提到的,这是非常不安全和不稳定的事情。

答案 2 :(得分:0)

试试这个

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 };

List<Category> items = new ArrayList<>();
String category = CATEGORIES[Integer.parseInt(scanner.nextLine())];   
items.add((Category)Class.forName(category)
    .getConstructor(ARGTYPES)
    .newInstance(myString, myInt));