当前位置:  开发笔记 > 编程语言 > 正文

Java代表?

如何解决《Java代表?》经验,为你挑选了6个好方法。

Java语言是否具有委托功能,类似于C#如何支持委托?



1> Matt Sheppar..:

不是,不是.

您可以通过使用反射获取然后可以调用的Method对象来实现相同的效果,另一种方法是使用单个"invoke"或"execute"方法创建一个接口,然后实例化它们以调用该方法你感兴趣的(即使用匿名的内部类).

您可能还会发现这篇文章有趣/有用:Java程序员看C#代表


使用invoke()作为接口的唯一成员函数的解决方案非常好.

2> Dave Cousine..:

根据您的意思,您可以使用策略模式实现类似的效果(传递方法).

而不是像这样的行声明一个命名的方法签名:

// 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
   }
}

然后,无论你SomeFunction在C#中拥有一个委托,只需使用一个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 */ });


+1.这是一个不错的解决方法,未来可维护性可以补偿冗长.

3> Patrick..:

短篇小说:不.

介绍

最新版本的Microsoft Visual J ++开发环境支持称为委托绑定方法引用的语言构造.此构造以及为支持它delegatemulticast引入的新关键字不是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需要有效地处理额外的和不同类型的引用和方法链接.


好文章.我喜欢他们对"简单"的定义:Java是一种简单的语言,如"Java必须简单地编写编译器/ VM",而忽略"Java必须简单地由人写/读" .解释了很多.
@Juozas:Python明确地被一个人编写/读取,并且它确实实现了lambda函数/委托**.
我只是觉得SUN犯了一个大错.他们只是没有被功能范式所信服,而这就是全部.
替换为archive.org链接.而且,那真是太愚蠢了,Oracle.

4> 小智..:

你读过这个:

代表是基于事件的系统中的有用构造.基本上,Delegates是对指定对象上的方法分派进行编码的对象.本文档展示了java内部类如何为这些问题提供更通用的解决方案.

什么是代表?实际上它非常类似于C++中使用的指向成员函数的指针.但是委托包含目标对象以及要调用的方法.理想情况下,能够说:

obj.registerHandler(ano.methodOne);

..并且当收到某个特定事件时,方法methodOne将在ano上调用.

这就是委托结构所实现的目标.

Java内部类

有人认为Java通过匿名内部类提供此功能,因此不需要额外的Delegate构造.

obj.registerHandler(new Handler() {
        public void handleIt(Event ev) {
            methodOne(ev);
        }
      } );

乍一看,这似乎是正确的,但同时也是一种麻烦.因为对于许多事件处理示例,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);
    }
  } );
}

最后*决赛*决赛

你注意了吗?

请注意,可以从匿名类方法定义中访问最终变量.请务必仔细研究此代码以了解其后果.这可能是一种非常强大的技术.例如,在MiniDOM中注册处理程序时以及更一般的情况下,它可以用于很好的效果.

相比之下,Delegate结构并没有为这个更一般的要求提供解决方案,因此应该作为设计可以基于的习语被拒绝.



5> 小智..:

我知道这篇文章很老,但Java 8添加了lambdas,以及功能接口的概念,这是任何只有一种方法的接口.它们共同提供与C#代理类似的功能.有关详细信息,请参阅此处,或者只是google Java Lambdas. http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html



6> Dominic Fox..:

不,但他们使用代理和反射是可伪造的:

  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> knockKnockDelegator = Delegator.ofMethod("knockKnock")
                                                                   .of(TestClass.class)
                                                                   .to(Callable.class);
      Callable callable = knockKnockDelegator.delegateTo(testInstance);
      assertThat(callable.call(), is("who's there?"));
  }

关于这个习惯用法的好处是,您可以在创建委托者的位置验证委托方法是否存在,并且具有所需的签名(尽管不是在编译时,但遗憾的是,虽然FindBugs插件可能帮助这里),然后安全地使用它委托给各种实例.

有关更多测试和实现,请参阅github上的karg代码.

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有