Java Delegates?

2020-01-24 06:07发布

Does the Java language have delegate features, similar to how C# has support for delegates?

13条回答
2楼-- · 2020-01-24 06:28

While it is nowhere nearly as clean, but you could implement something like C# delegates using a Java Proxy.

查看更多
来,给爷笑一个
3楼-- · 2020-01-24 06:29

I know this post is old, but Java 8 has added lambdas, and the concept of a functional interface, which is any interface with only one method. Together these offer similar functionality to C# delegates. See here for more info, or just google Java Lambdas. http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

查看更多
趁早两清
4楼-- · 2020-01-24 06:29

Yes & No, but delegate pattern in Java could be thought of this way. This video tutorial is about data exchange between activity - fragments, and it has great essence of delegate sorta pattern using interfaces.

Java Interface

查看更多
神经病院院长
5楼-- · 2020-01-24 06:31

Have you read this :

Delegates are a useful construct in event-based systems. Essentially Delegates are objects that encode a method dispatch on a specified object. This document shows how java inner classes provide a more generic solution to such problems.

What is a Delegate? Really it is very similar to a pointer to member function as used in C++. But a delegate contains the target object alongwith the method to be invoked. Ideally it would be nice to be able to say:

obj.registerHandler(ano.methodOne);

..and that the method methodOne would be called on ano when some specific event was received.

This is what the Delegate structure achieves.

Java Inner Classes

It has been argued that Java provides this functionality via anonymous inner classes and thus does not need the additional Delegate construct.

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

At first glance this seems correct but at the same time a nuisance. Because for many event processing examples the simplicity of the Delegates syntax is very attractive.

General Handler

However, if event-based programming is used in a more pervasive manner, say, for example, as a part of a general asynchronous programming environment, there is more at stake.

In such a general situation, it is not sufficient to include only the target method and target object instance. In general there may be other parameters required, that are determined within the context when the event handler is registered.

In this more general situation, the java approach can provide a very elegant solution, particularly when combined with use of final variables:

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);
    }
  } );
}

final * final * final

Got your attention?

Note that the final variables are accessible from within the anonymous class method definitions. Be sure to study this code carefully to understand the ramifications. This is potentially a very powerful technique. For example, it can be used to good effect when registering handlers in MiniDOM and in more general situations.

By contrast, the Delegate construct does not provide a solution for this more general requirement, and as such should be rejected as an idiom on which designs can be based.

查看更多
Root(大扎)
6楼-- · 2020-01-24 06:31

It doesn't have an explicit delegate keyword as C#, but you can achieve similar in Java 8 by using a functional interface (i.e. any interface with exactly one method) and 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();
}

Every new object of type SingleFunc must implement printMe(), so it is safe to pass it to another method (e.g. delegate(SingleFunc)) to call the printMe() method.

查看更多
该账号已被封号
7楼-- · 2020-01-24 06:32

Depending precisely what you mean, you can achieve a similar effect (passing around a method) using the Strategy Pattern.

Instead of a line like this declaring a named method signature:

// C#
public delegate void SomeFunction();

declare an interface:

// Java
public interface ISomeBehaviour {
   void SomeFunction();
}

For concrete implementations of the method, define a class that implements the behaviour:

// Java
public class TypeABehaviour implements ISomeBehaviour {
   public void SomeFunction() {
      // TypeA behaviour
   }
}

public class TypeBBehaviour implements ISomeBehaviour {
   public void SomeFunction() {
      // TypeB behaviour
   }
}

Then wherever you would have had a SomeFunction delegate in C#, use an ISomeBehaviour reference instead:

// C#
SomeFunction doSomething = SomeMethod;
doSomething();
doSomething = SomeOtherMethod;
doSomething();

// Java
ISomeBehaviour someBehaviour = new TypeABehaviour();
someBehaviour.SomeFunction();
someBehaviour = new TypeBBehaviour();
someBehaviour.SomeFunction();

With anonymous inner classes, you can even avoid declaring separate named classes and almost treat them like real delegate functions.

// Java
public void SomeMethod(ISomeBehaviour pSomeBehaviour) {
   ...
}

...

SomeMethod(new ISomeBehaviour() { 
   @Override
   public void SomeFunction() {
      // your implementation
   }
});

This should probably only be used when the implementation is very specific to the current context and wouldn't benefit from being reused.

And then of course in Java 8, these do become basically lambda expressions:

// Java 8
SomeMethod(() -> { /* your implementation */ });
查看更多
登录 后发表回答