【问题标题】:Dynamically instantiating an object in java在java中动态实例化一个对象
【发布时间】:2016-05-20 02:07:55
【问题描述】:

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

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

我将这些添加到 ArrayList 中。

那个 new 关键字似乎只接受一个实际的类,而不接受其他任何东西。我玩过内置的类方法,但是当我尝试在新调用之后放置这些方法时,它失败了。除了类本身失败之外,我在新调用之后放置的几乎所有东西都失败了。

这是可能的吗?

谢谢!

【问题讨论】:

  • 你在寻找反射。
  • 你可以instantiate the class using reflection。或者你可以使用 switch 语句。
  • 询问用户你必须实例化哪个类并不安全!
  • 查看工厂设计模式。它应该为您提供您正在寻找的东西。 link
  • 只需要一个开关。我知道我可以使用我只是在寻找一种“更清洁”的方式,但反射的东西看起来更复杂。谢谢大家!

标签: java class object dynamic


【解决方案1】:

【讨论】:

  • 我明白这是为了什么,但我不清楚如何让它真正发挥作用。如果我的子类上有构造函数,这个方法仍然有效吗?
【解决方案2】:

我不建议这样做,但可以使用反射:

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

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

这里可能会出错;这只有在以下都不成立时才有效:

  • 没有给定名称的类。
  • 用户说类似“String”而不是“java.lang.String”。 Class.forName(String s) 仅适用于完全限定名称。
  • 该类没有空构造函数(不带参数的构造函数)。

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

【讨论】:

【解决方案3】:

试试这个

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

【讨论】:

    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2013-03-29
    相关资源
    最近更新 更多