# What does :: mean in Java?

The `::` operator refers to a method reference. A method reference is a simplified way of writing a [lambda expression](https://techwithmaddy.com/java-8-lambda-expression) to call a method. Method references allow you to call a method by its name. The syntax for a method reference is as follows:

```plaintext
Object :: methodName
```

There are four ways to use a method reference:

* A method reference to a static method.
    
* A method reference to an instance method of an object.
    
* A method reference to instance methods of an arbitrary object of a particular type.
    
* A method reference to a constructor.
    

## Method reference to a static method

Let's take a look at the code snippet below:

```java
import java.util.function.BiFunction;

class Maths {

    public static int printAddition(int x, int y){
        return x + y;
    }

}
public class Main {

    public static void main(String[] args) {
        BiFunction<Integer, Integer, Integer> addition = Maths::printAddition;

        int result = addition.apply(2, 4);
        System.out.println("The result is: " + result);
        
    }

}
```

The outcome is:

```plaintext
The result is: 6
```

1. You have a non-static inner class called `Maths`**.**
    
2. Inside this inner class, you have a static method that given x and y returns the addition between x and y.
    
3. Then, you have the `Main` public class where you declare the main method so that you can execute our program.
    
4. Inside the main method, you have the BiFunction functional interface.
    

A BiFunction is a functional interface with three parameters: `T`, `U`, and `R`. In the example above, `T` and `U` are 2 and 4 respectively, which are both Integers. Your `R` is 6, which is again an Integer. In short, you are saying take a first Integer argument, then take a second Integer argument, and give me a result of Integer type. You can read more about BiFunction and other functional interfaces [here](https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html).

This is where you encounter the method reference. you take the name of the inner class (Maths), the `::` operator, and the name of the method `printAddition()`.

The BiFunction uses the method `apply()` to apply the method to the two arguments. In the example above, the arguments are 2 and 4. You assigned this operation to the result variable.

In the end, you print the outcome to the console.

## Method reference to an instance method of an object

```java
@java.lang.FunctionalInterface
interface Maths {

    void printAddition();

}
public class Main {

    public void printMessage(){
        System.out.println("Method reference to an instance method of an object");
    }

    public static void main(String[] args) {

        Main main = new Main();

        Maths reference = main::printMessage;

       reference.printAddition();

    }

}
```

The outcome is:

```plaintext
Method reference to an instance method of an object
```

1. You start the program with the functional interface `Maths`, which contains a `printAddition()` method.
    
2. The `Main` public class where there is a `printMessage()` method that prints out a message on the console.
    
3. In the main method, you instantiate an object called `main`.
    
4. Use the method reference on the object you created earlier.
    
5. Call the `printAddition()` via the reference variable of type Maths.
    

## Method reference to an instance method of an arbitrary object of a particular type

Let's consider the following program:

```java
package com.maddy;

public class Subject {

    private String name;
    private String assignment;


    public Subject(String name, String assignment) {
        this.name = name;
        this.assignment = assignment;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAssignment() {
        return assignment;
    }

    public void setAssignment(String assignment) {
        this.assignment = assignment;
    }

    public void print(){
        System.out.println("The name of the subject is: " + name + " and your assignment is: " + assignment);
    }
}
```

And this one as well:

```java
package com.maddy;

import java.util.ArrayList;
import java.util.List;

public class SubjectDemo {

    public static void main(String[] args) {

        List<Subject> subjects = new ArrayList<Subject>();

        subjects.add(new Subject("English", "Shakespeare"));
        subjects.add(new Subject("Geography", "Europe"));
        subjects.add(new Subject("History", " The Romans"));
        
        subjects.forEach(Subject::print);

    }
}
```

The outcome is:

```plaintext
The name of the subject is: English and your assignment is: Shakespeare
The name of the subject is: Geography and your assignment is: Europe
The name of the subject is: History and your assignment is: The Romans
```

Let's examine what is happening here:

1. You created a class `Subject` that has two fields: the subject's name, an *assignment*, a constructor and getters and setters. You also added a method that prints the name of the subject and its assignment.
    
2. Then you have a class called `SubjectDemo` where you create a list of Subject objects with some values.
    
3. You used the method reference to say that you want to apply the print method from the Subject class on each subject. A method reference can be called on an arbitrary method because in this case, you called the print method on all the subjects, not a particular one.
    

## **Method reference on a constructor**

Let's look at the following code snippet:

```java
package com.maddy;

@java.lang.FunctionalInterface
interface Geography {
    void print(String message);
}

class Test{

    public Test(String test) {
        System.out.println(test);
    }
}

public class GeographyTest {

    public static void main(String[] args) {

        Geography geography = Test::new;
        geography.print("Hello student! You've been assigned a Geography test. :) ");
    }
}
```

The outcome is:

```plaintext
Hello student! You've been assigned a Geography test. :)
```

Here, you're:

1. Creating a functional interface called `Geography` in which there is a method that prints a message.
    
2. An inner class called `Test` a constructor that initializes a test String and prints out the test itself when an object is created.
    
3. Use a method reference on the `Test` class constructor in the main method.
    
4. Finally, you print out a message.
    

Thanks for reading!
