Java语言是否具有委托特性,类似于c#对委托的支持?
当前回答
虽然它远没有那么干净,但您可以使用Java代理实现c#委托之类的东西。
其他回答
简短的故事:没有。
Introduction The newest version of the Microsoft Visual J++ development environment supports a language construct called delegates or bound method references. This construct, and the new keywords delegate and multicast introduced to support it, are not a part of the JavaTM programming language, which is specified by the Java Language Specification and amended by the Inner Classes Specification included in the documentation for the JDKTM 1.1 software. It is unlikely that the Java programming language will ever include this construct. Sun already carefully considered adopting it in 1996, to the extent of building and discarding working prototypes. Our conclusion was that bound method references are unnecessary and detrimental to the language. This decision was made in consultation with Borland International, who had previous experience with bound method references in Delphi Object Pascal. We believe bound method references are unnecessary because another design alternative, inner classes, provides equal or superior functionality. In particular, inner classes fully support the requirements of user-interface event handling, and have been used to implement a user-interface API at least as comprehensive as the Windows Foundation Classes. We believe bound method references are harmful because they detract from the simplicity of the Java programming language and the pervasively object-oriented character of the APIs. Bound method references also introduce irregularity into the language syntax and scoping rules. Finally, they dilute the investment in VM technologies because VMs are required to handle additional and disparate types of references and method linkage efficiently.
我知道这篇文章很旧了,但是Java 8增加了lambdas和函数接口的概念,即任何接口都只有一个方法。它们一起提供了与c#委托类似的功能。查看这里获得更多信息,或者只是谷歌Java Lambdas。 http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html
它不像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()方法是安全的。
不,但是它们可以通过代理和反射来伪装:
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#
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 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap