Java语言是否具有委托特性,类似于c#对委托的支持?
当前回答
虽然它远没有那么干净,但您可以使用Java代理实现c#委托之类的东西。
其他回答
虽然它远没有那么干净,但您可以使用Java代理实现c#委托之类的东西。
不,但是它们可以通过代理和反射来伪装:
public static class TestClass {
public String knockKnock() {
return "who's there?";
}
}
private final TestClass testInstance = new TestClass();
@Test public void
can_delegate_a_single_method_interface_to_an_instance() throws Exception {
Delegator<TestClass, Callable<String>> knockKnockDelegator = Delegator.ofMethod("knockKnock")
.of(TestClass.class)
.to(Callable.class);
Callable<String> callable = knockKnockDelegator.delegateTo(testInstance);
assertThat(callable.call(), is("who's there?"));
}
这种习惯用法的好处在于,您可以在创建委托器时验证委托方法是否存在,并具有所需的签名(不幸的是,在编译时不存在,尽管FindBugs插件在这里可能会有所帮助),然后安全地使用它来委托给各种实例。
有关更多测试和实现,请参阅github上的karg代码。
它不像c#那样有显式的委托关键字,但你可以在Java 8中通过使用函数接口(即任何只有一个方法的接口)和lambda来实现类似的功能:
private interface SingleFunc {
void printMe();
}
public static void main(String[] args) {
SingleFunc sf = () -> {
System.out.println("Hello, I am a simple single func.");
};
SingleFunc sfComplex = () -> {
System.out.println("Hello, I am a COMPLEX single func.");
};
delegate(sf);
delegate(sfComplex);
}
private static void delegate(SingleFunc f) {
f.printMe();
}
每个SingleFunc类型的新对象都必须实现printMe(),因此将它传递给另一个方法(例如委托(SingleFunc))来调用printMe()方法是安全的。
通过类路径上的安全镜像,你可以得到类似c#委托和事件的东西。
来自项目README的例子:
Java中的委托!
Delegate.With1Param<String, String> greetingsDelegate = new Delegate.With1Param<>();
greetingsDelegate.add(str -> "Hello " + str);
greetingsDelegate.add(str -> "Goodbye " + str);
DelegateInvocationResult<String> invocationResult =
greetingsDelegate.invokeAndAggregateExceptions("Sir");
invocationResult.getFunctionInvocationResults().forEach(funInvRes ->
System.out.println(funInvRes.getResult()));
//prints: "Hello sir" and "Goodbye Sir"
事件
//Create a private Delegate. Make sure it is private so only *you* can invoke it.
private static Delegate.With0Params<String> trimDelegate = new Delegate.With0Params<>();
//Create a public Event using the delegate you just created.
public static Event.With0Params<String> trimEvent= new Event.With0Params<>(trimDelegate)
看看这个SO的答案。
所描述的代码提供了c#委托的许多优点。方法,无论是静态的还是动态的,都可以以统一的方式处理。通过反射调用方法的复杂性降低了,而且代码是可重用的,因为在用户代码中不需要额外的类。请注意,我们调用的是invoke的另一个方便版本,其中只带一个参数的方法可以在不创建对象数组的情况下被调用。
class Class1 {
public void show(String s) { System.out.println(s); }
}
class Class2 {
public void display(String s) { System.out.println(s); }
}
// allows static method as well
class Class3 {
public static void staticDisplay(String s) { System.out.println(s); }
}
public class TestDelegate {
public static final Class[] OUTPUT_ARGS = { String.class };
public final Delegator DO_SHOW = new Delegator(OUTPUT_ARGS,Void.TYPE);
public void main(String[] args) {
Delegate[] items = new Delegate[3];
items[0] = DO_SHOW .build(new Class1(),"show,);
items[1] = DO_SHOW.build (new Class2(),"display");
items[2] = DO_SHOW.build(Class3.class, "staticDisplay");
for(int i = 0; i < items.length; i++) {
items[i].invoke("Hello World");
}
}
}
推荐文章
- Intellij IDEA Java类在保存时不能自动编译
- 何时使用Mockito.verify()?
- 在maven中安装mvn到底做什么
- 不可变与不可修改的集合
- 如何在JSON中使用杰克逊更改字段名
- GSON -日期格式
- 如何从线程捕获异常
- 无法解析主机"<URL here>"没有与主机名关联的地址
- 如何在Java中打印二叉树图?
- String.format()在Java中格式化双重格式
- com.jcraft.jsch.JSchException: UnknownHostKey
- Java中的操作符重载
- 如何加速gwt编译器?
- 在Hibernate中重新连接分离对象的正确方法是什么?
- 应该……接住环内还是环外?