简体   繁体   中英

Can I store an object constructor into an array or hashtable?

Let's say I have a class Foo and another class Bar that both extends from a superclass Foobar , each one with it's own constructor.

So, I want to make an application in Java 8 that let's a user choose from a list of objects to implement, and add them to a list —I was thinking of using an array or hashtable—, in this case I want to show a message like:

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

The idea is to let the user create multiple instances of such classes and add them to an array. For example, if the user chooses 1, I want to assign a variable with a[0] = new Foo() , and then if he chooses 2, a[1] = new Bar() , but then, if the user chooses 1 again, then a[2] should be a new instance of Foo . My first idea was to initialize an array with the constructors like:

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

The problem with that implementation is that if I call a[0] = anArray[1] and then a[1] = anArray[1] , then a[0] and a[1] would be the same object.

What I am looking for is if there is a way of creating an undefined number of instances of each object without having to implement it as a chain of if else (because in reality I have more than 2 type of objects). I was thinking of using an array or a hashtable, but I don't know if there is actually a way of doing it.

Suppose they implement a common interface (or superclass) Common :

public interface Common {
}

public class Foo implements Common {
}

public class Bar implements Common {
}

Then, in Java 8 we can define an array of Supplier s:

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

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

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

Usage:

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

Without a Common interface (or superclass) you'll have to do some less-than-ideal casting from Object .

Can I store an object constructor into an array or hashtable?

If you are in Java-8+ land then you certainly can. I'll assume you mean HashMap not a HashTable . I would instead create an array of Factory objects. Create a FooFactory and a BarFactory each which support create method that returns an object.

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

Then you can do:

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

And then you can use the array:

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

A select case statement will be most suitable for this. The problem here is this, unless they have a known superclass except object, they cannot be put in an array.So assuming that i will proceed. You can do this using java reflection API. There, you can load and create instance at runtime. For the array, make a Constructor[] . Study reflection to know what I mean. This might help you.

You are looking for the Factory pattern . In java 8 you can do it quite succinctly using lambda expressions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM