2017-04-09 88 views
0

我想在Java8中探索CompletableFuture,我写了这个简单的例子来消费假api,但我得到这个编译错误,我添加了围绕那段代码的try/catch块,但是我我仍然收到相同的编译错误。CompletableFuture:未处理的异常类型ExecutionException

* FakeAPI1 *

package com.fake.api; 

public class FakeAPI1 implements FakeAPI{ 

    @Override 
    public void consume(){ 
     try{ 
      Thread.sleep(1000L); 
      System.out.println("Hello from FakeAPI1"); 
     }catch(InterruptedException e){ 
      System.out.println("Eat it silently"); 
     } 
    } 

    public String getRandomText(){ 
     System.out.println("getRandomText() @ FakeAPI1 was called "); 
     try{ 
      Thread.sleep(1000L); 
      return "Hello from FakeAPI1"; 
     }catch(InterruptedException e){ 
      System.out.println("Eat it silently"); 
     } 
     return "Default message from FakeAPI1"; 
    } 
} 

* CompletableFutureTest *

package com.example.completablefuture; 

import java.util.Arrays; 
import java.util.List; 
import java.util.concurrent.CompletableFuture; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.Future; 
import java.util.stream.Collectors; 

import com.fake.api.FakeAPI1; 

public class CompletableFutureTest { 

    public static void main(String[] args) 
      throws InterruptedException,ExecutionException { 

     List<Future<FakeAPI1>> apis= 
       Arrays.asList(
        new CompletableFuture<FakeAPI1>(), 
        new CompletableFuture<FakeAPI1>(), 
        new CompletableFuture<FakeAPI1>() 
       ); 

     Long start= System.currentTimeMillis(); 
      apis.stream() 
       //Compilation error is in the line below 
       //Unhandled exception type ExecutionException 
       .map(api->api.get().getRandomText()) 
       .collect(Collectors.toList()); 


     Long end= System.currentTimeMillis(); 
     System.out.println("CompletableFutureTest took " + (end-start) + " ms"); 

    } 

} 

我在下面的答案添加try/catch块按照建议,编译错误不再显示但是当我运行代码时它什么也不做,看起来好像是在等待什么......

package com.example.completablefuture; 

import java.util.Arrays; 
import java.util.List; 
import java.util.concurrent.CompletableFuture; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.Future; 
import java.util.stream.Collectors; 

import com.fake.api.FakeAPI1; 

public class CompletableFutureTest { 

public static void main(String[] args) 
     throws InterruptedException,ExecutionException { 

    List<CompletableFuture<FakeAPI1>> apis= 
      Arrays.asList(
       new CompletableFuture<FakeAPI1>(), 
       new CompletableFuture<FakeAPI1>(), 
       new CompletableFuture<FakeAPI1>() 
      ); 

    Long start= System.currentTimeMillis(); 
    List<String> result= apis.stream() 
     .map(api-> { 
      try { 
       System.out.println("1"); 
       api.get().getRandomText(); 
      }catch (ExecutionException e) { 
       // TODO: return something else or throw a runtime exception 
       System.out.println("ExecutionException"); 
      }catch(InterruptedException e){ 
       // TODO: return something else or throw a runtime exception 
       System.out.println("InterruptedException"); 
      } 
      return "NA"; 
     }) 
     .collect(Collectors.toList()); 

    result.stream() 
      .forEach(System.out::println); 

    Long end= System.currentTimeMillis(); 
    System.out.println("CompletableFutureTest took " + (end-start) + " ms"); 

} 

} 

我添加了一个超时参数给get()方法,并开始投掷InterruptedException的

package com.example.completablefuture; 

    import java.util.Arrays; 
    import java.util.List; 
    import java.util.concurrent.CompletableFuture; 
    import java.util.concurrent.ExecutionException; 
    import java.util.concurrent.Future; 
    import java.util.concurrent.TimeUnit; 
    import java.util.concurrent.TimeoutException; 
    import java.util.stream.Collectors; 


    import com.fake.api.FakeAPI1; 

public class CompletableFutureTest { 

public static void main(String[] args) 
     throws InterruptedException,ExecutionException { 

    List<CompletableFuture<FakeAPI1>> apis= 
      Arrays.asList(
       new CompletableFuture<FakeAPI1>(), 
       new CompletableFuture<FakeAPI1>(), 
       new CompletableFuture<FakeAPI1>() 
      ); 

    Long start= System.currentTimeMillis(); 
    List<String> result= apis.stream() 
     .map(api-> { 
      try { 
       System.out.println("about to call get() method ..."); 
       api.get(1000L, TimeUnit.MILLISECONDS).getRandomText(); 
      }catch (ExecutionException e) { 
       // TODO: return something else or throw a runtime exception 
       System.out.println("ExecutionException"); 
      }catch(InterruptedException e){ 
       // TODO: return something else or throw a runtime exception 
       System.out.println("InterruptedException"); 
      }catch(TimeoutException e){ 
       // TODO: return something else or throw a runtime exception 
       System.out.println("InterruptedException"); 
      } 
      return "NA"; 
     }) 
     .collect(Collectors.toList()); 

    result.stream() 
      .forEach(System.out::println); 

    Long end= System.currentTimeMillis(); 
    System.out.println("CompletableFutureTest took " + (end-start) + " ms"); 

} 
} 

about to call get() method ... 
InterruptedException 
about to call get() method ... 
InterruptedException 
about to call get() method ... 
InterruptedException 
NA 
NA 
NA 
CompletableFutureTest took 3062 ms 
+0

未处理的异常类型ExecutionException –

+0

这是一个编译错误,不是一个异常 –

回答

2

你不要再追在正确的地方除外。 map()预计Function。而函数不能抛出任何检查的异常。因此,你需要

.map(api-> { 
    try { 
     return api.get().getRandomText()); 
    } 
    catch (ExecutionException e) { 
     // TODO: return something else or throw a runtime exception 
    } 
}) 
+0

我按照你的建议添加了try/catch打击,但它给了我这个编译错误:这个方法必须返回Object类型的结果。我在catch块之后添加了一个return语句,但是我又得到了相同的编译错误。 –

+0

很难解释为什么你的代码在没有看到你的代码的情况下有问题。你必须返回**的东西**。不只是回来。 –

+0

我为帖子添加了截图^^ –

1

当使用CompletableFuture,你应该使用join()方法,而不是get()。它们在功能上是相同的(在非例外情​​况下),但前者不会抛出检查的异常。

相关问题