Java 8 Consumer / Function Lambda Ambiguity

У меня есть перегруженный метод, который принимает Consumer и объект Function соответственно и возвращает универсальный тип, который соответствует соответствующему Consumer / Function. Я думал, что это будет хорошо, но когда я пытаюсь вызвать любой метод с лямбда-выражением, я получаю ошибку, указывающую, что ссылка на метод неоднозначна.

Основываясь на моем чтенииJLS §15.12.2.1. Определите потенциально применимые методы: похоже, что компилятор должен знать, что моя лямбда с блоком void соответствует методу Consumer, а моя лямбда с типом возврата соответствует методу Function.

Я собрал следующий пример кода, который не компилируется:

import java.util.function.Consumer;
import java.util.function.Function;

public class AmbiguityBug {
  public static void main(String[] args) {
    doStuff(getPattern(x -> System.out.println(x)));
    doStuff(getPattern(x -> String.valueOf(x)));
  }

  static Pattern<String, String> getPattern(Function<String, String> function) {
    return new Pattern<>(function);
  }

  static ConsumablePattern<String> getPattern(Consumer<String> consumer) {
    return new ConsumablePattern<>(consumer);
  }

  static void doStuff(Pattern<String, String> pattern) {
    String result = pattern.apply("Hello World");
    System.out.println(result);
  }

  static void doStuff(ConsumablePattern<String> consumablePattern) {
    consumablePattern.consume("Hello World");
  }

  public static class Pattern<T, R> {
    private final Function<T, R> function;

    public Pattern(Function<T, R> function) {
      this.function = function;
    }

    public R apply(T value) {
      return function.apply(value);
    }
  }

  public static class ConsumablePattern<T> {
    private final Consumer<T> consumer;

    public ConsumablePattern(Consumer<T> consumer) {
      this.consumer = consumer;
    }

    public void consume(T value) {
      consumer.accept(value);
    }
  }
}

Я также нашеланалогичный&nbsp;сообщение stackoverflow, которое оказалось ошибкой компилятора. Мой случай очень похож, хотя и немного сложнее. Для меня это все еще выглядит как ошибка, но я хотел убедиться, что я не неправильно понимаю спецификацию языка для лямбд. Я использую Java 8u45, которая должна иметь все последние исправления.

Если я изменю свои вызовы методов, чтобы они были обернуты в блок, кажется, что все компилируется, но это добавляет дополнительную многословность, и многие автоформаторы переформатируют его в несколько строк.

doStuff(getPattern(x -> { System.out.println(x); }));
doStuff(getPattern(x -> { return String.valueOf(x); }));