2025-02-11 07:00:05

Java代表?

Java语言是否具有委托特性,类似于c#对委托的支持?


当前回答

所描述的代码提供了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");
            }
        }
    }

其他回答

根据您的意思,您可以使用策略模式达到类似的效果(传递一个方法)。

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

// 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 8增加了lambdas和函数接口的概念,即任何接口都只有一个方法。它们一起提供了与c#委托类似的功能。查看这里获得更多信息,或者只是谷歌Java Lambdas。 http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

通过类路径上的安全镜像,你可以得到类似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的答案。

是或否,但是Java中的委托模式可以这样考虑。本视频教程讲的是活动片段之间的数据交换,具有使用接口的委托排序模式的精髓。