Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 functional constructor from templated object

I am using Eclipse Luna Service Release 2 (4.4.2), Java 8 u51.

I'm trying to create a method which will create instances of a passed object based on another method parameter. The prototype is simplified to

public <T> T test(Object param, T instance) {
    Constructor<?> constructor = instance.getClass().getConstructors()[0]; // I actually choose a proper constructor

    // eclipse reports "Unhandled exception type InvocationTargetException"
    Function<Object, Object> createFun = constructor::newInstance;

    T result = (T) createFun.apply(param);
    return result;
}

On line with Function declaration eclipse reports Unhandled exception type InvocationTargetException compiler error. I need the Function to later use in a stream.

I tried to add various try/catch blocks, throws declarations, but nothing fixes this compiler error.

How to make this code work?

like image 584
Dariusz Avatar asked Jul 17 '15 07:07

Dariusz


1 Answers

You can't throw a checked exception from a lambda with a Function target type because its apply method does not throw an exception. So you need to make it into an unchecked exception, for example by wrapping it:

Function<Object, Object> createFun = o -> {
  try {
    return constructor.newInstance(o);
  } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
    throw new RuntimeException(e);
  }
};

An alternative is to lead the compiler to think it's an unchecked exception, which produces a cleaner stack trace vs. the option above:

Function<Object, Object> createFun = o -> {
  try {
    return constructor.newInstance(o);
  } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
    return uncheck(e);
  }
};

With the following utility method:

@SuppressWarnings("unchecked")
public static <E extends Throwable, T> T uncheck(Throwable t) throws E {
  throw ((E) t);
}
like image 176
assylias Avatar answered Oct 30 '22 18:10

assylias