我有两个简单的类并使用反射模式调用方法。 我想写模块编程。 假设我们在数据库中有一个表,其中包含模块名称:
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
... ... ... ...
当 active 为真时,模块必须被激活。所以当我编写程序并编译它时,我不喜欢再次编译整个 MyApp。所以我使用反射模式来调用模块。请查看代码。
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);
}
}
}
输出
Call Method a
所以我听说在 Java 8 中,反射模式已被弃用,取而代之的是我们可以使用消费者和供应商。
如何在 java 8 中使用 consumer 和 supplier 而不是 Reflection?
谢谢。
最佳答案
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获取更多信息。
相对于反射的优势是显而易见的:
- 您不能要求
createInstanceAndCallMethod
创建一个不存在的类的实例。 - 您不能要求
createInstanceAndCallMethod
调用特定类中不存在的方法。 - 作为两者的结果,您不必处理任何已检查的异常。
当然,这只有在代码中的某个地方知道实际的类和方法时才有效,例如不可能从属性文件中读取类和方法名称,然后使用 Java 8 机制安全地创建实例并调用特定方法。
关于java - 如何使用 consumer 和 supplier 代替 java 8 中的 Reflection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42339586/