Java 基于类中的字段选择方法

Java 基于类中的字段选择方法,java,field,visitor-pattern,Java,Field,Visitor Pattern,所以我有一个包含字符串字段的类: public class A { private String type = ... public String getType(){ return this.type; } public void setType(String type){ this.type = type; } } 我还列出了所有可能的类型,有十二种,将来可能还会更多 现在我想编写一个方法,该方法获取类a的对象,并根据

所以我有一个包含字符串字段的类:

public class A {
    private String type = ...
    public String getType(){
        return this.type;
    }
    public void setType(String type){
        this.type = type;
    }
}
我还列出了所有可能的类型,有十二种,将来可能还会更多

现在我想编写一个方法,该方法获取类a的对象,并根据类中的“类型”调用特定的方法。 有没有比写12条(或更多)if语句更聪明的解决方案?
通常我会使用访问者模式,但我不想创建12个新类

编辑:
我最终创造了一个

Map<String,Function<A,String>> map = new HashMap<String,Function<A,String>>

如果您使用的是JDK 7或更高版本,请选择一个
开关
,该开关接受字符串作为参数,并为每个字符串编写大小写

  switch (type) {
         case "SomeX":
             yourInstance.invokeMethod();
             break;
         case "SomeY":
         ...

您应该使用
enum
,而不是将类型存储为“自由格式”文本值,因为您有一个定义良好的值列表

通过使用抽象方法,您甚至可以让不同的枚举以不同的方式实现相同的方法。这将允许您完全消除容易出错的
switch
语句

下面是一个显示实例值和抽象方法的示例。显示的模式将使实现不在枚举中,同时使编译器在添加新枚举时捕获所有使用

public enum Type {
    INTEGER("Integer") {
        @Override
        public void apply(Action action, A a) {
            action.applyInteger(a);
        }
    },
    STRING ("Text") {
        @Override
        public void apply(Action action, A a) {
            action.applyString(a);
        }
    };

    private String displayName;

    private Type(String displayName) {
        this.displayName = displayName;
    }

    public String getDisplayName() {
        return this.displayName;
    }

    public abstract void apply(Action action, A a);

}

public interface Action {

    public void applyInteger(A a);
    public void applyString(A a);

}

public class A {
    private Type type;
    public Type getType(){
        return this.type;
    }
    public void setType(Type type){
        this.type = type;
    }
    public void apply(Action action) {
        this.type.apply(action, this);
    }
}

将新类型添加到类型枚举时,还将向操作接口添加新方法,这将迫使您在接口的所有实现中实现该方法。使用
switch
语句,您不会得到这样的安全性。

我想其他答案是正确的,但通过阅读问题,我认为更直接的答案将是使用内省和惯例:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static class A {
        private String type;
        public String getType(){
            return this.type;
        }
        public void setType(String type){
            this.type = type;
        }
    }

    public static class Actions {

        public void runForType1(A a) {
            System.out.println("It's type 1");
        }

        public void runForType2(A a) {
            System.out.println("It's type 2");
        }

        public void runForType3(A a) {
            System.out.println("It's type 3");
        }
    }

    public static class Runner {
        Actions actions;
        public Runner(Actions a) {
            this.actions = a;
        }

        public void run(A a) {
            try {
                Method m = actions.getClass().getMethod("runFor" + a.getType(), A.class);
                m.invoke(actions, a);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Runner r = new Runner(new Actions());

        A type1 = new A();
        type1.setType("Type1");
        A type2 = new A();
        type2.setType("Type2");
        A type3 = new A();
        type3.setType("Type3");

        r.run(type1);
        r.run(type2);
        r.run(type3);
    }
}
示例的预期输出为:

It's type 1
It's type 2
It's type 3

如果无法使用约定,则始终可以创建具有类型到方法名称映射的哈希映射。

这些方法的作用是什么?为什么不把它们放在每种类型的班级里呢?听起来你愿意用代码质量换取几行节省下来的代码。你最终得到的解决方案比给出的答案要好(IMHO)。然而,Andreas关于enum优于string的建议可能值得注意。
It's type 1
It's type 2
It's type 3