Java语言是否具有委托特性,类似于c#对委托的支持?
当前回答
根据您的意思,您可以使用策略模式达到类似的效果(传递一个方法)。
而不是像这样的一行声明一个命名方法签名:
// C#
public delegate void SomeFunction();
声明一个接口:
// Java
public interface ISomeBehaviour {
void SomeFunction();
}
对于方法的具体实现,定义一个实现行为的类:
// Java
public class TypeABehaviour implements ISomeBehaviour {
public void SomeFunction() {
// TypeA behaviour
}
}
public class TypeBBehaviour implements ISomeBehaviour {
public void SomeFunction() {
// TypeB behaviour
}
}
然后在c#中使用SomeFunction委托的地方,使用ISomeBehaviour引用:
// C#
SomeFunction doSomething = SomeMethod;
doSomething();
doSomething = SomeOtherMethod;
doSomething();
// Java
ISomeBehaviour someBehaviour = new TypeABehaviour();
someBehaviour.SomeFunction();
someBehaviour = new TypeBBehaviour();
someBehaviour.SomeFunction();
使用匿名内部类,您甚至可以避免声明单独的命名类,几乎可以将它们视为真正的委托函数。
// Java
public void SomeMethod(ISomeBehaviour pSomeBehaviour) {
...
}
...
SomeMethod(new ISomeBehaviour() {
@Override
public void SomeFunction() {
// your implementation
}
});
这可能只应该在实现非常特定于当前上下文并且不会从重用中受益时使用。
当然,在Java 8中,这些基本变成了lambda表达式:
// Java 8
SomeMethod(() -> { /* your implementation */ });
其他回答
虽然它远没有那么干净,但您可以使用Java代理实现c#委托之类的东西。
根据您的意思,您可以使用策略模式达到类似的效果(传递一个方法)。
而不是像这样的一行声明一个命名方法签名:
// C#
public delegate void SomeFunction();
声明一个接口:
// Java
public interface ISomeBehaviour {
void SomeFunction();
}
对于方法的具体实现,定义一个实现行为的类:
// Java
public class TypeABehaviour implements ISomeBehaviour {
public void SomeFunction() {
// TypeA behaviour
}
}
public class TypeBBehaviour implements ISomeBehaviour {
public void SomeFunction() {
// TypeB behaviour
}
}
然后在c#中使用SomeFunction委托的地方,使用ISomeBehaviour引用:
// C#
SomeFunction doSomething = SomeMethod;
doSomething();
doSomething = SomeOtherMethod;
doSomething();
// Java
ISomeBehaviour someBehaviour = new TypeABehaviour();
someBehaviour.SomeFunction();
someBehaviour = new TypeBBehaviour();
someBehaviour.SomeFunction();
使用匿名内部类,您甚至可以避免声明单独的命名类,几乎可以将它们视为真正的委托函数。
// Java
public void SomeMethod(ISomeBehaviour pSomeBehaviour) {
...
}
...
SomeMethod(new ISomeBehaviour() {
@Override
public void SomeFunction() {
// your implementation
}
});
这可能只应该在实现非常特定于当前上下文并且不会从重用中受益时使用。
当然,在Java 8中,这些基本变成了lambda表达式:
// Java 8
SomeMethod(() -> { /* your implementation */ });
是或否,但是Java中的委托模式可以这样考虑。本视频教程讲的是活动片段之间的数据交换,具有使用接口的委托排序模式的精髓。
不,但它内部有相似的行为。
在c#中,委托用于创建一个单独的入口点,它们的工作原理很像函数指针。
在java中没有函数指针,但是在内部java需要做同样的事情来实现这些目标。
例如,在Java中创建线程需要一个类扩展Thread或实现Runnable,因为类对象变量可以用作内存位置指针。
不,但是它们可以通过代理和反射来伪装:
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代码。
推荐文章
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?
- “java”、“javaw”和“javaws”之间有什么区别?
- 将Date对象转换为日历对象
- 在Java中保存最后N个元素的大小有限的队列
- 如何运行一个类从Jar不是主类在其清单文件