Search code examples
javareflectionconsumer

How to use consumer and supplier instead Reflection in java 8


I have a two simple class and use reflection pattern for invoke method. I want to write module programming. Suppose we have a table in database that keep modules name:

Id  moduleName methodName   ClassName              active
1     sample     a           com.examle.sample        true  
2     SMS        sendSMS     com.example.SMS          false
3     Email      sendEmail   com.example.Email        false 
... ...          ...                       ...

When active is true the module must be activated.So when i write a program and compile that, i do not like again compile whole MyApp. So i use reflection pattern to invoke module. please see the codes.

public class Sample {
    public void a() {
        System.out.println("Call Method a");
    }
}
public class SMS {
    public void sendSMS(String str) {
        System.out.println("send SMS ok");
    }
}
public class Email {
    public void sendEmail(String str) {
        System.out.println("send Email ok");
    }
}
public class SampleMainClass {
    public static void main(String[] args) {

            //coonect to database and fetch all record in tables 
       while(record.next){
          if (record.getActive()){        
            Object o = Class.forName(record.getClssName()).newInstance() ;
            Method method = o.getClass().getDeclaredMethod(record.getMethodName());
            method.invoke(o);
          }                            
       }
    }

output

   Call Method a

So i heard in the java 8, reflection pattern is deprecate and instead that we can use consumer and supplier.

How to use consumer and supplier instead Reflection in java 8?

Thanks.


Solution

  • public class Q42339586 {
    
        static class Sample {
            void a() { System.out.println("a() called"); }
            void b() { System.out.println("b() called"); }
        }
    
        static <T> void createInstanceAndCallMethod(
                Supplier<T> instanceSupplier, Consumer<T> methodCaller) {
            T o = instanceSupplier.get();
            methodCaller.accept(o);
        }
    
        public static void main(String[] args) {
            createInstanceAndCallMethodJava8(Sample::new, Sample::a);
        }
    
    }
    

    Here, createInstanceAndCallMethod does what is done in your main() Method but it accepts parameters instead.

    A Supplier is used to create a new instance and a Consumer is used to call a particular method on that instance. In the example both method references are passed as both parameters. Instead, you could also use lambda expressions and write () -> new Sample() and o -> o.a() instead. Please refer to this official tutorial part for more information.

    The advantages over reflection are obvious:

    1. You cannot ask createInstanceAndCallMethod to create an instance of a class that doesn't exist.
    2. You cannot ask createInstanceAndCallMethod to call a method that doesn't exist in a particular class.
    3. As a result of both you don't have to deal with any checked Exception.

    Of course this does only work when at some place in the code the actual class and method are known, e.g. it's not possible to read class and method name from a properties file and then use Java 8 mechanisms to safely create an instance and call a particular method.