如何在java 8中使用消费者和供应商代替反射

时间:2017-02-20 08:23:37

标签: java reflection consumer

我有两个简单的类,并使用反射模式调用invoke方法。 我想写模块编程。 假设我们在数据库中有一个保存模块名称的表:

adam

当active为true时,必须激活模块。所以当我编写程序并编译时,我不喜欢再次编译整个MyApp。所以我使用反射模式来调用模块。请看代码。

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 
... ...          ...                       ...

输出

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);
          }                            
       }
    }

所以我在java 8中听到,反射模式是弃用的,而是我们可以使用消费者和供应商。

如何在java 8中使用消费者和供应商代替反射?

感谢。

2 个答案:

答案 0 :(得分:4)

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);
    }

}

在这里,createInstanceAndCallMethod执行main()方法中的操作,但它接受参数。

Supplier用于创建新实例,Consumer用于调用该实例上的特定方法。在示例中,两个方法引用都作为两个参数传递。相反,您也可以使用lambda表达式并写入() -> new Sample()o -> o.a()。有关详细信息,请参阅this official tutorial part

反思的优势显而易见:

  1. 您不能要求createInstanceAndCallMethod创建一个不存在的类的实例。
  2. 您不能要求createInstanceAndCallMethod调用特定类中不存在的方法。
  3. 由于您不必处理任何已检查的异常。
  4. 当然,只有在代码中的某个地方才能知道实际的类和方法,例如,无法从属性文件中读取类和方法名称,然后使用Java 8机制安全地创建实例并调用特定方法。

答案 1 :(得分:2)

Supplierfunction mouseover(bar) { d3.selectAll(".bar") .filter(function(d){ return (d != bar);}) .transition(t) .style("opacity", 0.5); } 是功能接口,它们不是指反射。

这是不同的事情。

  

所以我在java 8中听到,反射模式是弃用的,而是我们可以使用消费者和供应商。

错误的信息。