Over a million developers have joined DZone.

How Java 8 Binds Generic Types to Method References

DZone's Guide to

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 ·
Free Resource

Take 60 minutes to understand the Power of the Actor Model with "Designing Reactive Systems: The Role Of Actors In Distributed 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.

Learn how the Actor model provides a simple but powerful way to design and implement reactive applications that can distribute work across clusters of cores and servers. Brought to you in partnership with Lightbend.

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

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}