C# Delegate Equivalent in Java

Introduction

When you switch to a new programming language, you might miss some language features in the previous language. But, since many programming languages share the same features, you must be wondering what is the equivalent one in the new language you are going to use.

For example, you are switching from C# to Java and you want to use Delegate but you don’t know what is Delegate equivalent in Java. This article is going to explain the equivalent of Delegate in Java which is called Method Reference.

What is a Method Reference?

A method reference is a type of lambda expression that allows you to refer to an existing method by name. For example, if you have an existing method named square that takes an integer as parameter and returns the square value, you can use a method reference to call the square method.

To use a method reference, just place the :: symbol between the class name (or object) and the method name that you want to refer to. For example: ClassName::methodName or objectName::methodName. You can also use parentheses around the parameter list if needed (ClassName::methodName()).

For example, below code uses Method Reference along with Stream API as it is the most frequent use case.


public class ConsoleApp {
    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream().map(ConsoleApp::square).forEach(System.out::println);
    }

    public static int square(int num) {
        return num * num;
    }
}

If we don’t use Method Reference, then we have to put the logic within the lambda expression.


public class ConsoleApp {
    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream().map(x -> x * x).forEach(System.out::println);
    }
}

Definitely above example is very simple, but if we have complex logic then we should use Method Reference.

How to use Method Reference as a Delegate

Below we provide two equivalent code of C# and Java.

The C# one will be


internal class Program
{
    public delegate int DelegateMultiply(int a, int b);

    public static void Main(string[] args)
    {
        DelegateMultiply del = Program.Multiply;
        Console.WriteLine(del(3, 8));
    }

    public static int Multiply(int a, int b)
    {
        return a * b;
    }
}

In order to create the equivalent one in Java, we use Method Reference as Delegate. But, it cannot stand alone. It must be paired with Functional Interface.

Functional Interface is an interface that has only one abstract method. You can write the interface like usual or it is better to add @FunctionalInterface attribute to enforce the interface as Functional Interface.

In our case, we will create our Functional Interface as below:


@FunctionalInterface
interface Multiplier {
    int multiply(int a, int b);
}

And below is the complete code:


public class ConsoleApp {
    public static void main(String[] args) {

        Multiplier multiplier1 = (a, b) -> multiply(a, b);
        System.out.println(multiplier1.multiply(3, 8));

        Multiplier multiplier2 = ConsoleApp::multiply;
        System.out.println(multiplier2.multiply(3, 8));
    }

    public static int multiply(int a, int b) {
        return a * b;
    }
}

@FunctionalInterface
interface Multiplier {
    int multiply(int a, int b);
}

Conclusion

Method references together with Functional Interface in Java enables us to create the same Delegate feature as in C#. As we can see, achieving Delegate in Java is more verbose since Java doesn’t have exactly the same feature.