Vavr: Try.of and Try.run throw exceptions when using a static reference

Created on 6 Oct 2017  路  2Comments  路  Source: vavr-io/vavr

Steps

  1. use static reference on null string like this:
    public static void main(String[] args) {
    Optional str = Optional.empty();
    Try.run(() -> str.get().trim()); // This works perfectly, no exceptions thrown
    Try.run(str.get()::trim); // you will get NoSuchElementException
    // also
    Try.run(Integer.toString(1/0)::trim); // ArithmeticException
    }

Result

As I mentioned in comments I would get an exception.
I can't figure a way to suppress static reference exception when using Try.run or Try.of. Hope you can help me there; Otherwise it's either dont use static reference in Try.of or make another layer of Try.run/Try.of

Expected result

I would expect both static reference and simpe calls to work the same way - no exceptions are thrown

question

Most helpful comment

When you write str.get()::trim, the str.get() part of the expression is evaluated immediately to create a method reference to String::trim bound to the result of str.get(), but the invocation will throw outside of the Try.run(...) control flow, before the method reference object could be created.

On the other hand, the lambda expression works, because no exceptions will be thrown during creation of the lambda object, str.get() will only be invoked later, inside the Try.run(...) control flow.

The same thing will happen with Integer.toString(1/0)::trim, only with a different exception type.

See java.lang.NullPointerException is thrown using a method-reference but not a lambda expression if it's still unclear.

I suggest you close the issue.

All 2 comments

When you write str.get()::trim, the str.get() part of the expression is evaluated immediately to create a method reference to String::trim bound to the result of str.get(), but the invocation will throw outside of the Try.run(...) control flow, before the method reference object could be created.

On the other hand, the lambda expression works, because no exceptions will be thrown during creation of the lambda object, str.get() will only be invoked later, inside the Try.run(...) control flow.

The same thing will happen with Integer.toString(1/0)::trim, only with a different exception type.

See java.lang.NullPointerException is thrown using a method-reference but not a lambda expression if it's still unclear.

I suggest you close the issue.

Yep, @nfekete is right. Try can't catch an exception that thrown outside of the context of Try, i.e. before the JVM calls Try.run. Defer the exception by using a function instead.

Was this page helpful?
0 / 5 - 0 ratings