Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

238
Views
Expresiones Java Lambda y referencias de métodos a métodos genéricos

Tengo una interfaz funcional.

 import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; @FunctionalInterface public interface SubmitterCompletable extends Submitter { @Override <T> CompletableFuture<T> submit(Callable<T> task); }

y dos funciones

 import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; public final class CompletableFutureUtils { public static <U> CompletableFuture<U> runAsync(Callable<U> callable) { // ... } public static <U> CompletableFuture<U> runAsync(Callable<U> callable, Executor executor) { // ... } }

y quiero crear SubmitterCompletable s a partir de estas funciones usando expresiones lambda o referencias de métodos. El primero funciona bien usando referencias de métodos.

 SubmitterCompletable submitterCompletable = CompletableFutureUtils::runAsync;

Sin embargo, para el segundo, tengo que usar una expresión lambda para pasar un Executor y no funciona.

 Executor executor = /* ... */; SubmitterCompletable submitterCompletable = c -> CompletableFutureUtils.runAsync(c, executor); // Illegal lambda expression: Method submit of type SubmitterCompletable is generic

Mi pregunta es si hay una expresión lambda válida para este caso o tengo que crear una clase anónima en este caso.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Hay una expresión lambda válida, sin embargo, debe mover el tipo genérico en SubmitterCompletable del método al nivel de clase siempre que la expresión lambda no se pueda construir si el tipo genérico está definido en el método:

 @FunctionalInterface public interface SubmitterCompletable<T> extends Submitter { // notice the <T> @Override CompletableFuture<T> submit(Callable<T> task); // reuses the generic type }
 Executor executor = /* ... */; SubmitterCompletable<Whatever> submitterCompletable = c -> runAsync(c, executor);
over 4 years ago · Santiago Trujillo Report

0

El problema es que "una expresión lambda se puede usar para una interfaz funcional solo si el método en la interfaz funcional NO tiene parámetros de tipo". (JLS11, 15.27.3 Tipo de una expresión Lambda ) con una excepción: este no es el caso para las referencias de métodos congruentes .

Es por eso que funciona en su primer ejemplo y no en el segundo:

 SubmitterCompletable submitterCompletable = CompletableFutureUtils::runAsync; (OK) SubmitterCompletable submitterCompletable = c -> <anything> (NOT OK)

No hay muchas opciones que se me ocurran para lograr lo que quieres:

  1. Implemente la interfaz (ya sea en el lugar usando una clase anónima como mencionó o como una clase independiente).

  2. Use una clase auxiliar intermedia dentro de su CompletableFutureUtils que mantendría una referencia al ejecutor y expondría un método congruente con el método funcional de su remitente que delegará la llamada al método de utilidad subyacente runAsync(Callable<U> callable, Executor executor) .

Código de ejemplo:

 public final static class CompletableFutureUtils { public static <U> CompletableFuture<U> runAsync(Callable<U> callable) { ... } public static <U> CompletableFuture<U> runAsync(Callable<U> callable, Executor executor) { ... } public static ExecutorRunnerProxy using(Executor executor) { return new ExecutorRunnerProxy(executor); } public static final class ExecutorRunnerProxy { private final Executor executor; private ExecutorRunnerProxy(Executor executor) { this.executor = executor; } public <T> CompletableFuture<T> runAsync(Callable<T> task) { return CompletableFutureUtils.runAsync(task, executor); } } }

Ejemplo de uso:

 SubmitterCompletable submitterCompletable = CompletableFutureUtils::runAsync; SubmitterCompletable submitterWithExecutor = CompletableFutureUtils.using(executor)::runAsync;
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!