How to ensure completeness in an enum switch at compile time?

后端 未结 12 1042
悲&欢浪女
悲&欢浪女 2020-11-27 06:25

I have several switch statements which test an enum. All enum values must be handled in the switch statements by a case s

12条回答
  •  孤街浪徒
    2020-11-27 06:54

    This is a variant of the Visitor approach which gives you compile-time help when you add constants:

    interface Status {
        enum Pending implements Status {
            INSTANCE;
    
            @Override
            public  T accept(Visitor v) {
                return v.visit(this);
            }
        }
        enum Progressing implements Status {
            INSTANCE;
    
            @Override
            public  T accept(Visitor v) {
                return v.visit(this);
            }
        }
        enum Done implements Status {
            INSTANCE;
    
            @Override
            public  T accept(Visitor v) {
                return v.visit(this);
            }
        }
    
         T accept(Visitor v);
        interface Visitor {
            T visit(Done done);
            T visit(Progressing progressing);
            T visit(Pending pending);
        }
    }
    
    void usage() {
        Status s = getRandomStatus();
        String userMessage = s.accept(new Status.Visitor() {
            @Override
            public String visit(Status.Done done) {
                return "completed";
            }
    
            @Override
            public String visit(Status.Progressing progressing) {
                return "in progress";
            }
    
            @Override
            public String visit(Status.Pending pending) {
                return "in queue";
            }
        });
    }
    

    Beautiful, eh? I call it the "Rube Goldberg Architecture Solution".

    I would normally just use an abstract method, but if you really don't want to add methods to your enum (maybe because you introduce cyclic dependencies), this is a way.

提交回复
热议问题