Mat*_*ard 147
不是,不是.
您可以通过使用反射获取然后可以调用的Method对象来实现相同的效果,另一种方法是使用单个"invoke"或"execute"方法创建一个接口,然后实例化它们以调用该方法你感兴趣的(即使用匿名的内部类).
您可能还会发现这篇文章有趣/有用:Java程序员看C#代表
Dav*_*eau 61
根据您的意思,您可以使用策略模式实现类似的效果(传递方法).
而不是像这样的行声明一个命名的方法签名:
// C#
public delegate void SomeFunction();
Run Code Online (Sandbox Code Playgroud)
声明一个接口:
// Java
public interface ISomeBehaviour {
void SomeFunction();
}
Run Code Online (Sandbox Code Playgroud)
对于方法的具体实现,定义一个实现该行为的类:
// Java
public class TypeABehaviour implements ISomeBehaviour {
public void SomeFunction() {
// TypeA behaviour
}
}
public class TypeBBehaviour implements ISomeBehaviour {
public void SomeFunction() {
// TypeB behaviour
}
}
Run Code Online (Sandbox Code Playgroud)
然后,无论你SomeFunction在C#中拥有一个委托,只需使用一个ISomeBehaviour引用:
// C#
SomeFunction doSomething = SomeMethod;
doSomething();
doSomething = SomeOtherMethod;
doSomething();
// Java
ISomeBehaviour someBehaviour = new TypeABehaviour();
someBehaviour.SomeFunction();
someBehaviour = new TypeBBehaviour();
someBehaviour.SomeFunction();
Run Code Online (Sandbox Code Playgroud)
使用匿名内部类,您甚至可以避免声明单独的命名类,并且几乎将它们视为真正的委托函数.
// Java
public void SomeMethod(ISomeBehaviour pSomeBehaviour) {
...
}
...
SomeMethod(new ISomeBehaviour() {
@Override
public void SomeFunction() {
// your implementation
}
});
Run Code Online (Sandbox Code Playgroud)
这应该仅在实现非常特定于当前上下文时使用,并且不会从重用中受益.
然后当然在Java 8中,这些基本上变成了lambda表达式:
// Java 8
SomeMethod(() -> { /* your implementation */ });
Run Code Online (Sandbox Code Playgroud)
Pat*_*ick 36
介绍
最新版本的Microsoft Visual J ++开发环境支持称为委托或绑定方法引用的语言构造.此构造以及为支持它
delegate而multicast引入的新关键字不是Java TM 编程语言的一部分,Java语言规范由Java语言规范指定,并由JDKTM 1.1软件文档中包含的内部类规范进行修改.Java编程语言不太可能包含此构造.Sun已经仔细考虑过在1996年采用它,以建立和丢弃工作原型.我们的结论是绑定方法引用是不必要的并且对语言有害.该决定是在与Borland International协商后做出的,Borland International曾在Delphi Object Pascal中使用绑定方法引用.
我们认为绑定方法引用是不必要的,因为另一种设计选择,内部类,提供相同或更高的功能.特别是,内部类完全支持用户界面事件处理的要求,并且已经用于实现至少与Windows Foundation Classes一样全面的用户界面API.
我们认为绑定方法引用是有害的,因为它们有损于Java编程语言的简单性和API的普遍面向对象特性.绑定方法引用还会在语言语法和作用域规则中引入不规则性.最后,它们稀释了对VM技术的投资,因为VM需要有效地处理额外的和不同类型的引用和方法链接.
小智 18
你读过这个:
代表是基于事件的系统中的有用构造.基本上,Delegates是对指定对象上的方法分派进行编码的对象.本文档展示了java内部类如何为这些问题提供更通用的解决方案.
什么是代表?实际上它非常类似于C++中使用的指向成员函数的指针.但是委托包含目标对象以及要调用的方法.理想情况下,能够说:
obj.registerHandler(ano.methodOne);
..并且当收到某个特定事件时,方法methodOne将在ano上调用.
这就是委托结构所实现的目标.
Java内部类
有人认为Java通过匿名内部类提供此功能,因此不需要额外的Delegate构造.
obj.registerHandler(new Handler() {
public void handleIt(Event ev) {
methodOne(ev);
}
} );
Run Code Online (Sandbox Code Playgroud)
乍一看,这似乎是正确的,但同时也是一种麻烦.因为对于许多事件处理示例,Delegates语法的简单性非常有吸引力.
通用处理程序
但是,如果以更普遍的方式使用基于事件的编程,例如,作为一般异步编程环境的一部分,则存在更多的利害关系.
在这种一般情况下,仅包括目标方法和目标对象实例是不够的.通常,可能存在所需的其他参数,这些参数在注册事件处理程序时在上下文中确定.
在这种更一般的情况下,java方法可以提供非常优雅的解决方案,特别是与最终变量的使用相结合时:
void processState(final T1 p1, final T2 dispatch) {
final int a1 = someCalculation();
m_obj.registerHandler(new Handler() {
public void handleIt(Event ev) {
dispatch.methodOne(a1, ev, p1);
}
} );
}
Run Code Online (Sandbox Code Playgroud)
最后*决赛*决赛
你注意了吗?
请注意,可以从匿名类方法定义中访问最终变量.请务必仔细研究此代码以了解其后果.这可能是一种非常强大的技术.例如,在MiniDOM中注册处理程序时以及更一般的情况下,它可以用于很好的效果.
相比之下,Delegate结构并没有为这个更一般的要求提供解决方案,因此应该作为设计可以基于的习语被拒绝.
小智 13
我知道这篇文章很老,但Java 8添加了lambdas,以及功能接口的概念,这是任何只有一种方法的接口.它们共同提供与C#代理类似的功能.有关详细信息,请参阅此处,或者只是google Java Lambdas. http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html
不,但他们使用代理和反射是可伪造的:
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?"));
}
Run Code Online (Sandbox Code Playgroud)
关于这个习惯用法的好处是,您可以在创建委托者的位置验证委托方法是否存在,并且具有所需的签名(尽管不是在编译时,但遗憾的是,虽然FindBugs插件可能帮助这里),然后安全地使用它委托给各种实例.
| 归档时间: |
|
| 查看次数: |
232446 次 |
| 最近记录: |