Java Pass Method as Parameter

后端 未结 16 993
滥情空心
滥情空心 2020-11-22 02:17

I am looking for a way to pass a method by reference. I understand that Java does not pass methods as parameters, however, I would like to get an alternative.

I\'ve

相关标签:
16条回答
  • 2020-11-22 02:56

    Example of solution with reflection, passed method must be public

    import java.lang.reflect.Method;
    import java.lang.reflect.InvocationTargetException;
    
    public class Program {
        int i;
    
        public static void main(String[] args) {
            Program   obj = new Program();    //some object
    
            try {
                Method method = obj.getClass().getMethod("target");
                repeatMethod( 5, obj, method );
            } 
            catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                System.out.println( e ); 
            }
        }
    
        static void repeatMethod (int times, Object object, Method method)
            throws IllegalAccessException, InvocationTargetException {
    
            for (int i=0; i<times; i++)
                method.invoke(object);
        }
        public void target() {                 //public is necessary
            System.out.println("target(): "+ ++i);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:59

    Java do have a mechanism to pass name and call it. It is part of the reflection mechanism. Your function should take additional parameter of class Method.

    public void YouMethod(..... Method methodToCall, Object objWithAllMethodsToBeCalled)
    {
    ...
    Object retobj = methodToCall.invoke(objWithAllMethodsToBeCalled, arglist);
    ...
    }
    
    0 讨论(0)
  • 2020-11-22 03:01

    First define an Interface with the method you want to pass as a parameter

    public interface Callable {
      public void call(int param);
    }
    

    Implement a class with the method

    class Test implements Callable {
      public void call(int param) {
        System.out.println( param );
      }
    }
    

    // Invoke like that

    Callable cmd = new Test();
    

    This allows you to pass cmd as parameter and invoke the method call defined in the interface

    public invoke( Callable callable ) {
      callable.call( 5 );
    }
    
    0 讨论(0)
  • 2020-11-22 03:02

    In Java 8, you can now pass a method more easily using Lambda Expressions and Method References. First, some background: a functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.

    Without lambda expressions:

    obj.aMethod(new AFunctionalInterface() {
        @Override
        public boolean anotherMethod(int i)
        {
            return i == 982
        }
    });
    

    With lambda expressions:

    obj.aMethod(i -> i == 982);
    

    Here is an excerpt from the Java tutorial on Lambda Expressions:

    Syntax of Lambda Expressions

    A lambda expression consists of the following:

    • A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p, which represents an instance of the Person class.

      Note: You can omit the data type of the parameters in a lambda expression. In addition, you can omit the parentheses if there is only one parameter. For example, the following lambda expression is also valid:

      p -> p.getGender() == Person.Sex.MALE 
          && p.getAge() >= 18
          && p.getAge() <= 25
      
    • The arrow token, ->

    • A body, which consists of a single expression or a statement block. This example uses the following expression:

      p.getGender() == Person.Sex.MALE 
          && p.getAge() >= 18
          && p.getAge() <= 25
      

      If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively, you can use a return statement:

      p -> {
          return p.getGender() == Person.Sex.MALE
              && p.getAge() >= 18
              && p.getAge() <= 25;
      }
      

      A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have to enclose a void method invocation in braces. For example, the following is a valid lambda expression:

      email -> System.out.println(email)
      

    Note that a lambda expression looks a lot like a method declaration; you can consider lambda expressions as anonymous methods—methods without a name.


    Here is how you can "pass a method" using a lambda expression:

    interface I {
        public void myMethod(Component component);
    }
    
    class A {
        public void changeColor(Component component) {
            // code here
        }
    
        public void changeSize(Component component) {
            // code here
        }
    }
    
    class B {
        public void setAllComponents(Component[] myComponentArray, I myMethodsInterface) {
            for(Component leaf : myComponentArray) {
                if(leaf instanceof Container) { // recursive call if Container
                    Container node = (Container)leaf;
                    setAllComponents(node.getComponents(), myMethodInterface);
                } // end if node
                myMethodsInterface.myMethod(leaf);
            } // end looping through components
        }
    }
    
    class C {
        A a = new A();
        B b = new B();
    
        public C() {
            b.setAllComponents(this.getComponents(), component -> a.changeColor(component));
            b.setAllComponents(this.getComponents(), component -> a.changeSize(component));
        }
    }
    

    Class C can be shortened even a bit further by the use of method references like so:

    class C {
        A a = new A();
        B b = new B();
    
        public C() {
            b.setAllComponents(this.getComponents(), a::changeColor);
            b.setAllComponents(this.getComponents(), a::changeSize);
        }
    }
    
    0 讨论(0)
提交回复
热议问题