Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic class field in enum [duplicate]

public enum Dictionaries {
    FIRST_DICTIONARY(FirstDictionary.class),
    SECOND_DICTIONARY(SecondDictionary.class);

    private Class<? extends DictionaryModel> clazz;

    private Dictionary(Class<? extends DictionaryModel> clazz) {
        this.clazz = clazz;
    }

    public Class<? extends DictionaryModel> clazz() {
        return this.clazz;
    }
}

I have this enum. FirstDictionary and SecondDictionary implements DictionaryModel, it's a marker interface for sake of using this solution.

Right now I would love to do this:

Class<FirstDictionary> clazz = Dictionaries.FIRST_DICTIONARY.clazz();

It's obviously impossible with this design and I can't think of the way of achieving this. Is there any way to do this? I have access to the whole code, so I can modify everything, including the interface (or even remove it).

I simplified all of this, point is that every dictionary is a database table and I have one common DAO for them (instead of DAO for each dictionary), and now I have to cast the result of every read which I would like to avoid. I know that common DAO is not a good idea (or DAO at all).

Optional<DictionaryModel> entity = dao.getByValue(Dictionaries.FIRST_DICTIONARY, value);

I can't seem to a way even for any dynamic casts, in the DAO itself or in clazz() method. I feel like I'm missing something obvious here.

I appreciate any idea, even completely changing the design.

like image 216
Shadov Avatar asked Dec 24 '22 09:12

Shadov


1 Answers

As explained by Jorn Vernee, enum types do not allow this.

The most concise solution allowing you to write something like

Class<FirstDictionary> clazz = Dictionaries.FIRST_DICTIONARY.clazz();

would be

public interface Dictionaries<T extends DictionaryModel> {
    Dictionaries<FirstDictionary>  FIRST_DICTIONARY  = () -> FirstDictionary.class;
    Dictionaries<SecondDictionary> SECOND_DICTIONARY = () -> SecondDictionary.class;

    Class<T> clazz();
}

But you may reconcider whether getByValue really needs to receive an enum constant as argument instead of accepting a Class<T extends DictionaryModel> in the first place.

like image 170
Holger Avatar answered Dec 28 '22 22:12

Holger