StephanM StephanM - 1 year ago 80
Java Question

Create new instance class reference

I have an Enum like this:

public static enum TestEnum {
// main
ENUM_A (1, "test1", TestADto.class),
ENUM_B (2, "test2", TestBDto.class),
ENUM_C (3, "test3", TestCDto.class),
...

private Class<? extends Dto> dtoClass;

public Class<? extends Dto getDtoClass() {
return dtoClass;
}

...
}


All of these dto classes extend the same abstract (dto) class:

public abstract class AbstractDto {

private String foo;

private int bar;

...

AbstractDto(AbstractClassNeededForInitialization o) {
this.foo = o.getFoo();
this.bar = o.getBar();
}

... some functions here ...
}


This would a example Dto implementation of TestADto:

@Getter
@Setter
public class TestADto extends AbstractDto {

private String anotherFoo;

private int anotherBar;

...

public TestADto(AbstractClassNeededForInitialization o) {
super(o);
}

... some functions here ...
}


Is it possible (im using Java 8) create a concrete instance of these in the enum reference classes without the need of knowing which concrete istance it is?

Lets say im at a certain point in a function and im having the Enum_A. Now i want to create a dto instance (TestADto.class). What would be the best approach or pattern for this?

Imagine a enum with more than 100 entries and every entry has a different dto which extends the same abstract dto or implements a interface.

How can i create these concrete object without writing a huge if else or switch statement or handle it case by case.

I read something about reflection and proxies but not sure if this is the right way i am. Or is the current state im having already a kind of poor design?
Everything i want to reach is to assign the dto name to an enum for creating it later at some certain points. But without creating a huge condition if possible...

@Edit

I forgot to mention that creating a instance of each dto needs to have object which is passed to the constructor. This object which is passed to the constructor also implements a interface.

Answer Source

If you need to invoke an empty constructor for your DTO subclasses, you could provide a Supplier in the enum constructor that you store in a field :

...
ENUM_A  (1, "test1", TestADto::new),
ENUM_B  (2, "test2", TestBDto::new),
ENUM_C  (3, "test3", TestCDto::new);

private Supplier<Dto> supplierDto;

TestEnum(int i, String name, Supplier<Dto> supplierDTO){
    this.supplierDto = supplierDTO;
    ...
}
...

Then you can create the Dto instance by invoking supplierDto.get();


After your edit :

I forgot to mention that creating a instance of each dto needs to have object which is passed to the constructor.

A Supplier<Dto> doesn't suit any longer as it is not designed to be used with a constructor that presents one parameter.

By Supposing that your constructors are like that :

public class TestADto{
    ...
   private MyInterface myInterface;

   public TestADto (MyInterface myInterface){
       this.myInterface = myInterface;
   }
    ...    
}

You could so declare in the enum constructor a Function <MyInterface, Dto> parameter to match to this constructor.

...
ENUM_A  (1, "test1", TestADto::new),
ENUM_B  (2, "test2", TestBDto::new),
ENUM_C  (3, "test3", TestCDto::new);

private Function <MyInterface, Dto> myInterfaceToDtoFunction;

TestEnum(int i, String name, Function <MyInterface, Dto> myInterfaceToDtoFunction){
    this.myInterfaceToDtoFunction = myInterfaceToDtoFunction;
    ...
}

public Dto createInstance(MyInterface myInterface){
    return myInterfaceToDtoFunction.apply(myInterface);
}

...
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download