Over a million developers have joined DZone.

How Java 8 Binds Generic Types to Method References

You may be aware of referencing instances of static methods, but this could help you look at binding in a whole new way.

· Java Zone

What every Java engineer should know about microservices: Reactive Microservices Architecture.  Brought to you in partnership with Lightbend.

So most of the time you are probably aware of method references that reference instances of static methods directly, and they are useful but not necessarily that interesting.

Integer example = 1;

// We can bind the instance variables, in this case just the return type is bound but there couple be method parameters also
Supplier<String> s = example::toString;

// We can bind to static method, here the generic parameter are the method parameter and return type
Supplier<Long> f = System::currentTimeMillis;
Function<Integer,Integer> f = example::compareTo;

 A less common formulation is to pass in instance methods and find the first generic parameter of of the function to be the type; this allows you to easily pass in a range of actions to operate on a common type:

Function<Integer,String> f = Integer::toString

For example, you can create an equals method that works on a subset of properties using functions mapped to instance methods as in the above example:

public static <T> boolean equals(T one, T two, Function<? super T, ?>... accessors) {

    if (one == two) {
        return true;
    } else  if (one==null || two==null) {
        return false;

    return Stream.of(accessors).allMatch(accessor ->

if (equals(one, two, Thing::getName, Thing:getOtherProperty)) ...;

Finally you can also bind the exception thrown from the method to one of the generic parameters. (Here I am using ThrowingException and ThrowingSupplier my home brew interfaces that are like there namesakes but have a generic parameter E for the exception thrown) This allows you to make you "closure" transparent to exceptions. This is more useful in a lot of cases when compared to the Stream throw nothing and "throws Exception" extremes.
ThrowingException<String,Integer,NumberFormatException> te = Integer::parseInt;

You can write funky closure methods that will throw different exceptions based on the passed-in method reference--no more catch (Exception).

public static <T, E extends Exception> T withCC(Class<?> contextClass, 
   ThrowingSupplier<T,E> action) throws E {

    Thread t = Thread.current();
    ClassLoader cl = t.getContextClassLoader();
    try {
        return action.get();
    } finally {

// Throws IOException, complier knows that this method call throws IOException

withCC(Example.class, () -> {
    ... new FileOutpuStream(file); ...

// Throws another exception, complier knows that this method call throws RMIExeption

withCC(Example.class, () -> {
        throw new RMIException();

Once you understand the last two, method references start to become far more interesting.

Microservices for Java, explained. Revitalize your legacy systems (and your career) with Reactive Microservices Architecture, a free O'Reilly book. Brought to you in partnership with Lightbend.

instance,static,method,references,java,java 8

Published at DZone with permission of Gerard Davison, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}