【问题标题】:In Java, it is possible to take a line of code as a method argument?在Java中,可以将一行代码作为方法参数吗?
【发布时间】:2014-03-05 03:08:01
【问题描述】:

我似乎在谷歌上找不到任何东西,我不确定这是否可能。我想做的是将一行Java代码作为参数传递给方法。 Google 仅显示将 cmd 行参数传递给方法的结果,但我想传递实际的代码行。

基本上我想将methodA传递给methodB,除了methodA不是方法,而是一行代码。下面是使用反射将方法传递给方法的完整示例。

public class Relation<T> {

protected Set<Pair<T,T>> pairs = null;

public Relation() {
    this.pairs = new LinkedHashSet<Pair<T,T>>();
}

    /* Next 2 methods are methods for sending methods to methods useing java.lang.reflect.Method */
    public Method getMethod(String name) {
        try {   return Relation.class.getDeclaredMethod(name);
        } catch (Exception e) {} 
        return null;
    }

    public boolean execute(Method method, Object... params) {
        try {   return (Boolean) method.invoke(this, params);
        } catch (Exception e) {}
        return false;
    }

    /* The method I reuse several times so I just put methods inside of it */   
    public boolean pairsTFIterator(Method method)  {
        for(Pair<T,T> x : pairs) {
            boolean bool = false;
            for(Pair<T,T> y : pairs) {
                if(execute(method, x,y))    
                    bool = true; break;
            }
            if(!bool) return false;
        }
        return true;
    }

    /* To be replaced by the line of code*/   
    public static <T> boolean isSymmetricPairs(Pair<T,T> a, Pair<T,T> b) {
        return a.getFirst().equals(b.getSecond()) && a.getSecond().equals(b.getFirst()) ? true :false;
    }

    /* Method that calls others */
    public boolean isSymmetric() {
        return pairsTFIterator(getMethod("isSymmetricPairs"));
    }
}

以上方法都很好,但我想更进一步,只是放弃像“isSymmetricPairs”方法这样的方法,只需将方法逻辑行直接放在“pairsTFIterator”中,如下所示:

public boolean isReflexive() {  
    return  baseSetTFIterator(
            a.getFirst().equals(b.getSecond()) && a.getSecond().equals(b.getFirst()) ? true :false
    );
}

我很确定这是不可能的,但如果有办法做到这一点,那就太好了。

【问题讨论】:

  • 不,这是不可能的。您可以解析该行并生成相应的代码。一些表达式语言会这样做。
  • 这是 Java。执行此操作的惯用方法(直到 Java 8 and lambdas)是创建一个接口并匿名实现它,就像您在 Java 中使用任何其他类似事件的习语一样。
  • 我不太了解您的规格。是否需要重新选择,或者您能否了解如何使用 v8 Lambda 或(8 之前的)Functor 来封装您想要的内容? Functor 是一个“函数”,但显然可以将一行代码封装成一个......假设您不是试图“即时”编写代码。我昨天刚写了这个:stackoverflow.com/questions/7369460/…。如果我理解你,这个答案(这确实是一篇成熟的博客文章)应该会有所帮助。

标签: java reflection methods arguments


【解决方案1】:

听起来您正在寻找的是“一流的功能”。有些语言将函数视为变量,因为您可以将它们分配给变量并将它们作为参数传递给其他函数。 Java 8 将引入支持此类功能的 lambda 表达式的概念。

还有其他 JVM 语言已经提供了这个功能,包括 Scala 和 Groovy,仅举两个比较流行的语言。

只是为了让您了解它的外观,在 Groovy 中,您可以通过调用 each() 方法并向其传递一个闭包(本质上是一个函数)来对集合的每个元素执行任意函数。

def list = [1, 2, 3, 4]
def printer = { x -> println x } // defines a closure that takes one arg and prints it
list.each(printer) // prints out the elements

def sum = 0
def summer = { x -> sum += x } // defines a closure that takes one arg and adds it to the sum variable
list.each(summer)
println sum // should be 1 + 2 + 3 + 4

【讨论】:

    【解决方案2】:

    将您的代码放在匿名内部类中可能会满足您的要求:

        interface PairFilter<T>{
            boolean filter(Pair<T, T> a, Pair<T,T> b);
        }
    

    在你的迭代器方法中:

        public boolean pairsTFIterator(PairFilter filter) {
            for(Pair<T,T> x : pairs) {
                boolean bool = false;
                for(Pair<T,T> y : pairs) {
                    if(filter.filter(x,y))    
                        bool = true; break;
                    }
                    if(!bool) return false;
            }
            return true;
        }
    

    然后调用它:

        pairsTFIterator(new PairFilter<T>(){
            public boolean filter(Pair<T, T> a, Pair<T,T> b){
                return a.getFirst().equals(b.getSecond()) && a.getSecond().equals(b.getFirst()) ? true :false;
            }
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-19
      • 2015-12-29
      • 1970-01-01
      • 2011-02-24
      • 2013-10-19
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多