0
votes

Type Enum générique pour tout ce qui est étendu

J'aime créer une énumération générique qui accepte tout.

Pour cet exemple, j'utilise TaskStatus, mais à l'avenir, j'aime utiliser Generic Enum par exemple; StudentStatus, ce statut d'étudiant peut prendre un identifiant et une description et il se convertira automatiquement. De plus, itérer chaque objet et enfin revenir automatiquement. Y a-t-il une chance que je puisse y arriver?

 @Getter
 @AllArgsConstructor(access = AccessLevel.PRIVATE)
  public enum TaskStatusEnum{
    
        READY(1, "Ready"),
        ON_GOING (2,"On going");
        
        private final long id;
        private final String description;
        
        
        public static TaskStatusEnum get (long id)
        {
            for (TaskStatusEnum status : TaskStatusEnum.values()) {
                if (status.id == id) {
                    return id;
                }
            }
            return null;
        }


7 commentaires

Qu'entendez-vous par «étendu». Voulez-vous dire ajouter dynamiquement une troisième ou quatrième énumération au-delà des deux indiquées ici? Ou est-ce que vous sous-classez une énumération en définissant une autre énumération?


J'aime créer une nouvelle énumération et donner un nom à Enum et quand j'étends une énumération générique, elle doit être remplie automatiquement


Je ne suis toujours pas. Comprenez-vous qu'une énumération est fondamentalement un moyen pratique d'instancier automatiquement quelques objets nommés statiques?


is TaskStatus enum peut être sous-classé pour une énumération générique?


Aucun sous-classement de votre énumération. Voir ma réponse.


Merci de votre réponse


Vous pouvez utiliser l'interface comme classe de base et énumérer les implémentations par cette interface. Ensuite, utilisez le statut comme interface. La sous-classe d'interface sera votre énumération de statut


3 Réponses :


0
votes

Votre énumération est effectivement finale (aucune sous-classe autorisée)

Apparemment, vous demandez si l'énumération TaskStatus peut être sous-classée. Par exemple, créer un StudentStatus qui hérite de TaskStatus .

➥ Non, les énumérations en Java ne peuvent pas être sous-classées.

Votre définition d'énumération est en fait une sous-classe de Enum . Cela se produit en arrière-plan, géré comme par magie par le compilateur . L'héritage s'arrête là. Votre définition d'énumération est en fait finale , ne permettant pas d'autres sous-classes.

Une définition d'énumération peut implémenter un interface . Les instances de plusieurs définitions d'énumérations peuvent être traitées comme étant toutes des objets de la même interface. Voir Réponse de Victor1125 .

Une énumération en Java est un moyen pratique d'instancier automatiquement un ou plusieurs objets de nom, pour représenter un ensemble limité de valeurs connues au moment de la compilation. Ces instances apparaissent toutes lorsque leur classe de définition est chargée par le chargeur de classe Java . Ces objets restent en mémoire.

Vous ne pouvez pas ajouter dynamiquement d'autres instances au moment de l'exécution. L'ensemble du domaine des objets de l'énumération est défini au moment de la compilation. (Exception: un code de réflexion / introspection tordu peut être capable de créer plus d'instances, mais je n'irais pas là-bas.)

Si vous voulez l'héritage ou des instances créées dynamiquement, n'utilisez pas d'énumérations. Utilisez des classes et des sous-classes régulières, rassemblées dans des ensembles ou des listes. Les ensembles ou listes peuvent être marqués ( <…> ) avec des génériques pour permettre la superclasse de leurs éléments contenus. Par exemple, Set peut contenir des objets des sous-classes Dog , Cat et Bird .

Au fait, vous pouvez maintenant définir une énumération à 3 endroits: sa propre classe, imbriquée dans une autre classe, et maintenant dans Java 16 (prévisualisé dans Java 15), localement dans une méthode.

Astuce: inutile de mettre "Enum" dans le nom de votre énumération. Efforcez-vous d'inventer des noms pour votre classe enum et des objets enum qui se lisent naturellement. Le fait qu'il s'agisse d'une énumération devrait disparaître en arrière-plan. Par exemple: voir Mois ( Month.JANUARY ) et DayOfWeek ( DayOfWeek.MONDAY ).


3 commentaires

Bonjour Basil, le code semble fonctionner mais je ne sais pas comment convertir cette énumération avec mapsturct. Enum que j'écrivais fonctionnait taskResponse.setTaskStatus (TaskStatus.get (taskList.getTaskSt‌ atus ()). Name ()); mais je ne sais pas comment faire avec un prolongé


@John Vous m'avez perdu avec votre taskList indéfinie et votre "liste étendue" inexpliquée.


Merci Basil, je l'ai trié. J'expliquais la classe de base. Mais je ne pouvais pas gérer les avertissements nuls. Puis-je gérer null sur la classe StaticUtils ci-dessous



2
votes

Je ne sais pas exactement ce que vous voulez. Vous pouvez utiliser l'interface sur enum, puis vous pouvez utiliser l'interface comme statut sans vous soucier de ce qu'est exactement la classe de statut.

    public static void main(String... args) {
    StudentStatus studentStatus = StatusUtil.get(StudentStatus.class, 0);
    TaskStatus taskStatus = StatusUtil.get(TaskStatus.class, 0);
    
    List<Status> statusList = Arrays.asList(studentStatus, taskStatus);
    for(Status status: statusList) {
        System.out.println(status.getClass().getName()+"\t"+status.getId()+"\t"+status.getDescription());
    }
}

statut d'étudiant:

public abstract class StatusUtil {

    public static <E extends Enum<E>> E get(Class<E> statusClass, long id) {
    for(E item: (E[]) statusClass.getEnumConstants()) {
        if(item.getId() == id) {
            return item;
        }
    }
    return null;
}

état de la tâche:

public interface Status<E extends Enum<E>> {

    public long getId();
    public String getDescription();

} 

méthode générique pour connaître l'état par identifiant

public class Test {

    public static void main(String... args) {
        StudentStatus studentStatus = StatusUtil.get(StudentStatus.class, 0);
        TaskStatus taskStatus = StatusUtil.get(TaskStatus.class, 0);
    
        List<Status> statusList = Arrays.asList(studentStatus, taskStatus);
        statusList.forEach(status -> System.out.println(status.getClass().getName()+"\t"+status.getId()+"\t"+status.getDescription()));
    }
}

exemple d'utilisation: p >

public abstract class StatusUtil {

public static <E extends Enum<E> & Status<E>> E get(Class<E> statusClass, long id) {
        return Arrays.asList((E[]) statusClass.getEnumConstants())
            .stream()
            .filter(item -> item.getId() == id)
            .findAny()
            .orElse(null);
    }
}

si vous utilisez JAVA inférieur à 8:

public enum TaskStatus implements Status<TaskStatus>{

    OPEN(0, "open");

    ;

    private long id;
    private String description;

    private TaskStatus(long id, String description) {
        this.id=id;
        this.description = description;
    }

    @Override
    public long getId() {
        return id;
    }

    @Override
    public String getDescription() {
        return description;
    }
}

statusUtil:

public enum StudentStatus implements Status<StudentStatus>{

    NEW(0, "new");

    ;

    private long id;
    private String description;

    private StudentStatus(long id, String description) {
        this.id=id;
        this.description = description;
    }

    @Override
    public long getId() {
        return id;
    }

    @Override
    public String getDescription() {
        return description;
    }

}

} test:

public interface Status<E extends Enum<E> & Status<E>> {

    public long getId();
    public String getDescription();

}

Ceci vous pouvez utiliser dans les cas où enums a les mêmes méthodes et que vous avez besoin d'une interface commune


1 commentaires

Merci d'avoir répondu exactement à ce dont j'ai besoin, mais je dois utiliser la méthode get sur mon exemple foreach pour le mappage et également la méthode de nom pour enum que j'utilisais comme; taskResponse.setTaskStatus (TaskStatus.get (taskList.getTaskSt‌ atus ()). name ()); pour mapstruct



0
votes

Comment gérer le point nul sur StatusUtil.class

StatusUtil:

Classe abstraite publique StatusUtil {

 public static <E extends Enum<E>> E get(Class<E> statusClass, long id) {
    for(E item: (E[]) statusClass.getEnumConstants()) {
        if(item.getId() == id) {
            return item;
        }
    }
    return null;
}


0 commentaires