1

I have the following code

   public class FunctionalInterfaceTest {

  @FunctionalInterface
  public interface FunctionThatThrows<T, R> {
    R apply(T t) throws Exception;
  }

  public void perform() {
    try {
      unchecked((String x) -> Integer.parseInt(x)).apply("abc");
    } catch (Exception e) {
      System.out.println("Encountered exception" + e.getMessage());
    }
  }

  public void perform1() {
    try {
      unchecked(<fill-in-here-using-method-reference>);
    } catch (Exception e) {
      System.out.println("Encountered Exception" + e.getMessage());
    }
  }

  public <T, R> Function<T, R> unchecked(FunctionThatThrows<T, R> f) {
    return (a) -> {
      try {
        return f.apply(a);
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    };
  }

  public static void main(String[] args) {
    FunctionalInterfaceTest test = new FunctionalInterfaceTest();
    test.perform();
    test.perform1();
  }
}

I want to use Method Reference in the perform1 method to get similar result as in the perform method. I tried using a method reference like Integer::parseInt in perform1 but it doesnt work. How do I do the same with a method reference and why is the method reference giving an error?

5
  • Did you try unchecked((FunctionThatThrows<String, Integer>) Integer::parseInt).apply("abc")? and that didn't work which way? Commented May 10, 2020 at 11:47
  • @Naman That works. Why is the explicit typecast necessary? Commented May 10, 2020 at 11:51
  • how many parseInt are there that can potentially match your Integer::parseInt? When you cast, you explicitly say to the compiler which parseInt to use Commented May 10, 2020 at 13:10
  • I thought its quite explicit that we are using parseInt from the java.lang.Integer. Why would that be ambiguous? Commented May 10, 2020 at 13:20
  • 1
    I don't know why the compiler doesn't pick up the right method, but is this a problem with a practical relevance? I mean, in real life you would use the result, like Function<String,Integer> f = unchecked(Integer::parseInt);... Commented May 10, 2020 at 15:56

1 Answer 1

1

How do I do the same with a method reference and why is the method reference giving an error?

You can't, unless there is an explicit type present. Since the unchecked method uses generic parameter FunctionThatThrows<T, R> the compiler doesn't know what these generic types T and R are. The following will not compile:

unchecked(s -> Integer.parseInt(s));    // doesn't compile

The compiler thinks s is an Object which is not compatible with Integer.parseInt(String s) method. That's why the it is ambiguous.

The point is, there must be explicitly stated the type of the generic parameter. There are three ways to define the type and keep generic solution.

  1. As you have already done, specify that s is String using downcasting.

    unchecked((String x) -> Integer.parseInt(x))                 // no method reference
    
  2. Use an explicit casting of the passed lambda expression. This solution is the first one that IntelliJ Idea offers to me. Now it is clear for the compiler input and output for the passed function is String and Integer respectively. Note this structure is what Integer.parseInt(String s) requires`:

    unchecked((FunctionThatThrows<String, Integer>) Integer::parseInt); // with method reference
    
  3. Explicitly, define a required return type:

    Function<String, Integer> f = unchecked((FunctionThatThrows<String, Integer>) Integer::parseInt);
    

    .. the redundant casting should be omitted and it gives a more clear result:

    Function<String, Integer> f = unchecked(Integer::parseInt);  // with method reference
    

    (Note @Holger also brought this one in the comments)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.