【问题标题】:Can I store an object constructor into an array or hashtable?我可以将对象构造函数存储到数组或哈希表中吗?
【发布时间】:2017-08-23 04:09:58
【问题描述】:

假设我有一个类 Foo 和另一个类 Bar,它们都从超类 Foobar 扩展而来,每个类都有自己的构造函数。

所以,我想在 Java 8 中创建一个应用程序,让用户从要实现的对象列表中进行选择,并将它们添加到列表中——我正在考虑使用数组或哈希表——在这种情况下,我想要显示如下消息:

Choose an object of the following list:
 [1] Foo
 [2] Bar

这个想法是让用户创建此类类的多个实例并将它们添加到数组中。比如用户选择1,我想给变量赋值a[0] = new Foo(),然后如果他选择2,a[1] = new Bar(),但是,如果用户再次选择1,那么a[2]应该是一个新的实例的Foo。我的第一个想法是使用以下构造函数初始化一个数组:

anArray[1] = new Foo();
anArray[2] = new Bar();

该实现的问题在于,如果我调用a[0] = anArray[1],然后调用a[1] = anArray[1],那么a[0]a[1] 将是同一个对象。

我正在寻找的是是否有一种方法可以创建每个对象的未定义数量的实例,而不必将其实现为if else 链(因为实际上我有超过 2 种类型的对象)。我在考虑使用数组或哈希表,但我不知道是否真的有办法做到这一点。

【问题讨论】:

  • 什么 Java 版本?
  • 构造函数通过反射以Constructor 的形式提供,因此您可以将它们存储到某个数组或集合中(然后通过newInstance() 调用它们)。但是,您可能希望改用工厂对象。或者,您可以使用anArray[1] = new Foo(); 等,然后通过调用a[0] = anArray[1].clone() 等创建副本。
  • @weston 我正在使用 Java 8
  • anArray 的类型是什么?有共同的基类吗?
  • @AndrewS 是的,它们都是从一个共同的超类扩展而来的

标签: java arrays class constructor hashtable


【解决方案1】:

假设他们实现了一个公共接口(或超类)Common

public interface Common {
}

public class Foo implements Common {
}

public class Bar implements Common {
}

那么,在 Java 8 中我们可以定义一个Suppliers 的数组:

List<Supplier<Common>> anArray = new ArrayList<>();

anArray.add(Foo::new);
anArray.add(Bar::new);

//or with lambdas:
anArray.add(() -> new Bar());

用法:

Common aNewCommon = anArray.get(0).get();

如果没有Common 接口(或超类),您将不得不从Object 进行一些不太理想的转换。

【讨论】:

  • 如果方法有一个公共超类而不是一个公共接口,这是否会以同样的方式工作?
【解决方案2】:

我可以将对象构造函数存储到数组或哈希表中吗?

如果您在 Java-8+ 领域,那么您当然可以。我假设您的意思是HashMap 不是HashTable。相反,我会创建一个 Factory 对象数组。创建一个FooFactory和一个BarFactory,每个都支持返回一个对象的create方法。

 public interface MyFactory<T> {
      public T create();
 }

 public class FooFactory implements MyFactory<Foo> {
      public Foo create() {
          return new Foo();
      }
 }

 public class BarFactory implements MyFactory<Bar> {
      public Bar create() {
          return new Bar();
      }
 }

那么你可以这样做:

MyFactory[] factories = new MyFactory[10];
factories[0] = new FooFactory();
factories[1] = new BarFactory();
...

然后就可以使用数组了:

Object obj = factories[0].create();

【讨论】:

  • 也许可以解释一下为什么你要创建所有这些样板,因为它是 Java 8?
  • 嘿,你的回复得到了赞成票,但答案没有。去图吧。
  • 好一个@weston! :-)
【解决方案3】:

选择案例语句将最适合于此。 这里的问题是,除非它们具有除对象之外的已知超类,否则它们不能放入数组中。所以假设我会继续。 您可以使用 java 反射 API 来做到这一点。 在那里,您可以在运行时加载和创建实例。 对于数组,创建一个Constructor[]。研究反思以了解我的意思。 这可能会对您有所帮助。

【讨论】:

  • 我认为Object 类型的数组可以容纳每个对象?
  • 当然,但是作为一个超类对于任何目的来说都太通用了,除非你知道用户给定的选择要创建的对象的class。这就是反射出现的原因。
  • 这就是我支持选择案例的原因
  • 无偿反思是无偿的。
【解决方案4】:

您正在寻找Factory pattern。在 java 8 中,您可以非常简洁地使用 lambda 表达式。

【讨论】:

    猜你喜欢
    • 2011-02-27
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    相关资源
    最近更新 更多