I was exploring the Java 8 source and found this particular part of code very surprising:
//defined in IntPipeline.java
@Override
public fin
So I see here tons of answers that are frankly overcomplicated, and that's an understatement.
The answer is pretty simple: :: it's called a Method References https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
So I won't copy-paste, on the link, you can find all the information if you scroll down to the table.
Now, let's take a short look at what is a Method References:
A::B somewhat substitutes the following inline lambda expression: (params ...) -> A.B(params ...)
To correlate this with your questions, it's necessary to understand a java lambda expression. Which is not hard.
An inline lambda expression is similar to a defined functional interface (which is an interface that has no more and no less than 1 method). Let's take a short look what I mean:
InterfaceX f = (x) -> x*x;
InterfaceX must be a functional interface. Any functional interface, the only thing what's important about InterfaceX for that compiler is that you define the format:
InterfaceX can be any of this:
interface InterfaceX
{
public Integer callMe(Integer x);
}
or this
interface InterfaceX
{
public Double callMe(Integer x);
}
or more generic:
interface InterfaceX
{
public T callMe(U x);
}
Let's take the first presented case and the inline lambda expression that we defined earlier.
Before Java 8, you could've defined it similarly this way:
InterfaceX o = new InterfaceX(){
public int callMe (int x, int y)
{
return x*x;
} };
Functionally, it's the same thing. The difference is more in how the compiler perceives this.
Now that we took a look at inline lambda expression, let's return to Method References (::). Let's say you have a class like this:
class Q {
public static int anyFunction(int x)
{
return x+5;
}
}
Since method anyFunctions has the same types as InterfaceX callMe, we can equivalate those two with a Method Reference.
We can write it like this:
InterfaceX o = Q::anyFunction;
and that is equivalent to this :
InterfaceX o = (x) -> Q.anyFunction(x);
A cool thing and advantage of Method References are that at first, until you assign them to variables, they are typeless. So you can pass them as parameters to any equivalent looking (has same defined types) functional interface. Which is exactly what happens in your case