有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

有人能推荐Java8模式来代替switch语句吗?

我有以下代码:

 public class A {
    private String type;
    String getType() { return type;}
 }

现在在很多代码地方我都有这样的代码

 switch (a.geType()) {
  case "A" : return new Bla();
  case "B" : return new Cop();
 }

或者别的什么地方

switch (a.geType()) {
  case "A" : return new Coda();
  case "B" : return new Man();
 }

(请注意,我知道应该在生产代码中使用枚举)

我想实现的是,当一个新类型被添加到类a中时,编译器应该标记所有需要调整的switch语句

有没有java惯用的方法来实现这一点


共 (4) 个答案

  1. # 1 楼答案

    不要忘记好的老式多态性。在类中有一个带有switch语句的“type”字段通常是一种气味,表明子类化可能很有用。考虑:

    public abstract class CommonSuperClass {
        public abstract One getOne();
        public abstract Two getTwo();
    }
    
    public class A extends CommonSuperClass {
        @Override public One getOne() { return new Bla(); }
        @Override public Two getTwo() { return new Coda(); }
    }
    
    public class B extends CommonSuperClass {
        @Override public One getOne() { return new Cop(); }
        @Override public Two getTwo() { return new Man(); }
    }
    

    如果要添加新的子类C,则需要提供抽象方法的实现(除非使C本身成为抽象的)

  2. # 2 楼答案

    when a new type is added to class A the compiler should flag all the switch statements that need to be adjusted?

    解决这一问题的一个好方法是用更健壮的多分派实现替换switch语句,例如Visitor Pattern

    interface VisitorOfA {
        Object visitA(A a);
        Object visitB(B b);
    }
    class A {
        Object accept(VisitorOfA visitor) {
            return visitor.visitA(this);
        }
    }
    class B extends A {
        Object accept(VisitorOfA visitor) {
            return visitor.visitB(this);
        }
    }
    

    有了这个基础结构,您可以删除switch语句,用访问者的实现替换它们:

    Object res = a.accept(new VisitorOfA() {
        public Object visitA(A a) { return new Bla(); }
        public Object visitB(B b) { return new Cop(); }
    });
    

    当您向A添加一个新的子类型时,比如说,class C,您需要做的就是向VisitorOfA添加一个新方法:

    Object visitC(C c);
    

    现在,编译器将发现这个新方法尚未实现的所有地方,帮助您避免运行时出现问题

  3. # 3 楼答案

    从抽象的角度来看,您可以使用另一种方法。一种方式是通过Polymorphism as shown here

    一些简单的例子:

    public void EverythingYouWant (Animal animal) {
        return animal.move();
    }
    

    当更多的是关于重构replace type code/checking with State/Strategy模式时。这是一个很好的解决方案,首先考虑是否有防止子类化的原因。

  4. # 4 楼答案

    您可以拥有字符串/供应商的地图:

    Map<String, Supplier<Object>> map = new HAshMap<> ();
    map.put("A", Bla::new);
    map.put("B", Cop::new);
    

    您的示例代码将变成:

    return map.get(a.getType()).get(); //need null check