我有两个简单的类,并使用反射模式进行调用方法。我想编写模块编程。假设我们在数据库中有一个保留模块名称的表:
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
... ... ... ...
当活动为真时,必须激活模块。因此,当我编写程序并编译该模块时,我不喜欢再次编译整个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中使用消费者和供应商反思?
谢谢。
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()
。请参阅此官方教程部分以获取更多信息。
与反射相比的优点很明显:
- 您不能要求
createInstanceAndCallMethod
创建一个不存在的类的实例。 - 您不能要求
createInstanceAndCallMethod
调用特定类中不存在的方法。 - 由于两者都不必处理任何检查的例外。
当然,这只有在代码中的某个位置时才能使用实际类和方法,例如无法从属性文件读取类和方法名称,然后使用Java 8机制安全创建实例并调用特定方法。
Consumer
和 Supplier
是功能接口,它们不参考反射。
这是不同的事情。
所以我在Java 8中听到了反射模式,而我们可以使用消费者和供应商。
错误的信息。