如何调用一个名为java中字符串变量值的方法?

时间:2014-07-11 21:54:54

标签: java string methods

这是我想要简化的方法的代码。我调用SerializedExpFamMixture类的方法名称正是“模型”的值,我的问题是如何将“model”的值直接指定为方法的名称,而不是使用“if”来确定哪个方法我应该打电话。由于使用“if”,我需要列出“模型”的所有可能值,并判断我应该使用哪种方法。

非常感谢您的帮助。我是java的新手。

public static SerializedExpFamMixture RateMtxModel(String model)
 {
   SerializedExpFamMixture result=new SerializedExpFamMixture();
   if(model=="kimura1980()")
     result=SerializedExpFamMixture.kimura1980();
   if(model=="accordance()")
     result=SerializedExpFamMixture.accordance();
   if(model=="pair()")
     result=SerializedExpFamMixture.pair();
   return result;

 } 

3 个答案:

答案 0 :(得分:2)

您可以采用的一种方法是使用Reflection:

Method method = myClass.getClass().getMethod("doSomething", null);
method.invoke(myClass, null);

答案 1 :(得分:0)

使用反射,但您需要考虑以下几点:

  1. 错误提醒!使用==比较字符串在java中无法正常工作 - 请改用.equals()。但是,下面的解决方案绕过了这个问题
  2. 对于包含调用者不可见的方法的一般情况,您需要考虑辅助功能,无论是在找到方法还是调用它
  3. 您不需要result变量,即使使用您的代码,也不需要初始化
  4. 试试这个:

    String methodName = model.replace("(", "").replace(")", "");
    try {
        // getMethod() returns only public methods, getDeclaredMethod() returns any visibility
        Method method = SerializedExpFamMixture.class.getDeclaredMethod(methodName);
        // if the method is not guaranteed to be visible (eg public) you need this:
        method.setAccessible(true);
        return (SerializedExpFamMixture) method.invoke(null); // how to invoke on the class object
    } catch (Exception forBrevity) {
        return new SerializedExpFamMixture();
    }
    

答案 2 :(得分:0)

由于您不熟悉Java,现在是时候提出一些指示:

  1. 在Java中,我们通常使用camelCase命名我们的方法,因此第一个字母是小写。
  2. 另外,在Java中,我们通常将开头的花括号放在与代码相同的行上(没有换行符)。
  3. 始终对变量使用final。至少你的参数。这样你就不会覆盖它,因此不必试图找出它在运行时实际具有的值。
  4. 使用大括号!请!
  5. 实际上并不需要result变量。
  6. 使用equals - 方法比较String s。
  7. 如果您只想要一个结果,请使用else-if
  8. 修复这些问题,您的方法如下所示:

    public static SerializedExpFamMixture rateMtxModel(String model) {
       if (model.equals("kimura1980()")) {
         return SerializedExpFamMixture.kimura1980();
       } else if (model.equals("accordance()")) {
         return SerializedExpFamMixture.accordance();
       } else if(model.equals("pair()")) {
         return SerializedExpFamMixture.pair();
       } 
       return new SerializedExpFamMixture();
    }  
    

    接下来,让我们来看看你在这里尝试做什么。您希望传递一些String,并将它们用作创建对象的基础。现在,根据这里给出的建议,你将使用反射来做到这一点。这对我来说听起来不是一个好主意。说你要经历这个,这发生了:

    rateMtxModel("kinura1980");
    

    难以发现的小错字会带来意想不到的结果。如果你实际上正在调用一个方法,那么编译器会让你知道你搞砸了,现在你不会得到任何警告(顺便说一下,你在这个方法调用中看到了两个错误吗?)。如果有人要删除accordance() - 方法,编译器也不会提醒他们这会破坏程序。

    如果是,我会直接使用SerializedExpFamMixture中的静态工厂方法,但是如果你必须这样做(如果手头的任务是使用String输入创建一个对象)我会做这样的事情:

    public enum Something {
        KIMURA1980("kimura1980()"),
        ACCORDANCE("accordance()"),
        PAIR("pair()");
    
        private final String stringValue;
    
        private Something(final String stringValue) {
            this.stringValue = stringValue;
        }
    
        public static Something fromString(final String string) {
            for (final Something something : values()) {
                if (something.stringValue.equals(string)) {
                    return something;
                }
            }
            return null;
        }
    }
    
    public static SerializedExpFamMixture rateMtxModel(final String model) {
       if (model == null) {
           throw new IllegalArgumentException("model is null!");
       }
    
       final Something something = Something.fromString(model);
    
       if (something == null) {
          return new SerializedExpFamMixture();
       }
    
       switch(something) {
           case KIMURA1980:
               return SerializedExpFamMixture.kimura1980();
           case ACCORDANCE:
               return SerializedExpFamMixture.accordance();
           case PAIR:
               return SerializedExpFamMixture.pair();
           default:
               return new SerializedExpFamMixture();    
       }   
    }  
    

    这样,你将使用String的地方是枚举,其余的代码将使用枚举常量,因此具有编译器依赖的安全性。

    还可以将操作和String之间的链接留给枚举,如下所示:

    interface Operation<T> {
        public T run(); 
    }
    
    public enum Something {
        KIMURA1980("kimura1980()", new Operation<SerializedExpFamMixture>() {
                                          public SerializedExpFamMixture run() { 
                                              return SerializedExpFamMixture.kimura1980();
                                          } 
                                   }) ,
        ACCORDANCE("accordance()", new Operation<SerializedExpFamMixture>() {
                                           public SerializedExpFamMixture run() { 
                                               return SerializedExpFamMixture.accordance();
                                           } 
                                   }),
        PAIR("pair()", new Operation<SerializedExpFamMixture>() {
                               public SerializedExpFamMixture run() { 
                                   return SerializedExpFamMixture.pair();
                               } 
                       }),
        DEFAULT(null, new Operation<SerializedExpFamMixture>() {
                              public SerializedExpFamMixture run() { 
                                  return new SerializedExpFamMixture();
                              } 
                      });
    
        private final String stringValue;
        private final Operation<SerializedExpFamMixture> operation;
    
        private Something(final String stringValue, final Operation<SerializedExpFamMixture> operation) {
            this.stringValue = stringValue;
            this.operation = operation;
        }
    
        public static Something fromString(final String string) {
            if (string != null) {
                for (final Something something : values()) {
                    if (string.equals(something.stringValue)) {
                        return something;
                    }
                }
            }
            return DEFAULT;
        }
    
        public SerializedExpFamMixture getCorrespondingSerializedExpFamMixture() {
            return operation.run();
        }
    }
    

    在enum中使用此设置(我认为可以使用Java8修剪Operation - 部分),该方法将如下所示:

    public static SerializedExpFamMixture rateMtxModel(String model) {
        return Something.fromString(model).getCorrespondingSerializedExpFamMixture();
    }