Java 8 Lambda in details part III : Method and constructor referencing

In this third post dedicated to Java 8 Lambda expressions, we’ll look at the new :: operator introduced to allow method and constructor referencing.

DISCLAIMER: all the details exposed in this post were observed related to the JDK 8 demo version as of July 10th 2012. Since the JDK is still in beta, some assertions may not hold in future

Please note that all the example code in this post can be found on my GitHub repository https://github.com/doanduyhai/Java8_Lambda_In_Details

 

I Method referencing

With the JDK 8 it is possible to create a lambda expression by aliasing an existing method in a class. For this the new :: operator has been introduced. It is possible to reference a method:

  1. from its class if it was declared static
  2. from an instance variable of from the this keyword for non-static methods
public interface MethodReferenceSAM
{
	String process(String input);
}

public class MethodReference
{
	public static String toUpperStatic(String input)
	{
		return input.toUpperCase();
	}

	public String toUpperInstance(String input)
	{
		return input.toUpperCase();
	}

	public String toUpperFromThis(String input)
	{
		MethodReferenceSAM sam = this::toUpperInstance;
		return sam.process(input);
	}

	public static void main(String... args)
	{
		MethodReferenceSAM sam = MethodReference::toUpperStatic;
		System.out.println("nntstatic method reference = "+sam.process("static_input"));
		
		MethodReference methodReference = new MethodReference();
		sam = methodReference::toUpperInstance;
		System.out.println("nntinstance method reference = "+sam.process("instance_input"));
		
		System.out.println("nnt"this" method reference = "+methodReference.toUpperFromThis("this_input"));
		System.out.println("");
	}
}

The output:

static method reference = STATIC_INPUT

instance method reference = INSTANCE_INPUT

“this” method reference = THIS_INPUT

Pretty straightforward. With this feature, we can create a method (static or not) and possibly assigned it as lambda expression to two different SAM (Single Abstract Method) interface, as long as the method signatures match.

Example

public interface SAM1
{
	String process(String input);
}

public interface SAM2
{
	String differentName(String input);
}

...
SAM1 sam1 = MethodReference::toUpperStatic;

SAM1 sam2 = MethodReference::toUpperStatic;

The above code example can be found on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the MethodReference.bat(MethodReference.sh) script

 

II Constructor referencing

Constructor referencing is quite similar to method referencing. The SAM interface method should have the same signature as the constructor method being used.

public interface ConstructorReferenceSAM<T>
{
	T whatEverMethodName();
}

public interface ConstructorReferenceSAMWithArgs<T, U>
{
	T createMeANewObject(U arg);
}

public interface ConstructorReferenceSAMWithParameterizedArg<T, U>
{
	T magic(List<U> arg);
}

public class ConstructorReference
{

	private String content;

	private List<String> contents;

	public ConstructorReference() {
		this.content = "created by constructor reference";
	}

	public ConstructorReference(String content) {
		this.content = content;
	}

	public ConstructorReference(List<String> contents) {
		this.contents = contents;
	}

	public String getContent()
	{
		return content;
	}

	public List<String> getContents()
	{
		return contents;
	}

	public static void main(String... args)
	{
		ConstructorReferenceSAM<ConstructorReference> constructorSam = ConstructorReference::new;
		System.out.println("nntcontent = "+constructorSam.whatEverMethodName().getContent());
		
		ConstructorReferenceSAMWithArgs<ConstructorReference,String> constructorSamWithArg = ConstructorReference::new;		
		System.out.println("nntcontent by arg = "+constructorSamWithArg.createMeANewObject("created by constructor reference with arg").getContent());
		
		ConstructorReferenceSAMWithParameterizedArg<ConstructorReference,String> constructorSamWithParameterizedArg = ConstructorReference::<String>new;
		System.out.println("nntcontents size by parameterized arg = "+constructorSamWithParameterizedArg.magic(new ArrayList<String>()).getContents().size());
		System.out.println("");
		
	}
}

The output:

content = created by constructor reference

content by arg = created by constructor reference with arg

contents size by parameterized arg = 0

For constructor with parameterized arguments, please notice the special syntax for referencing (line 53) ConstructorReference::<String>new;

The above code example can be found on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the ConstructorReference.bat(ConstructorReference.sh) script

To be continued …
 
 

5 Comments

  1. Pingback: Java – far sight look at JDK 8 | Transylvania JUG

  2. About Java

    informative post about java 8 lambda.. thanks for sharing.. 🙂

    Reply
    1. DuyHai DOAN

      You’re welcomed 🙂

      Reply
  3. toronto mold removal

    Terrific stuff. Have you considered that this is material that could be submitted on an
    official online article database?

    Reply
    1. DuyHai DOAN

      Thank you for your remarks.

      For the moment, my materials are based on a beta version of lambda and until it is officially released, many things can change.

      So honestly I prefer to wait until the lambda is stabilized before putting those articles somewhere.

      Reply

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.