在 JDK 8 中将函数作为参数传递

Passing function as argument in JDK 8

我正在尝试重构以下代码

class FileDownloadResource{

   @Inject
   private FileDownload fileDownload;

    @Path(/abc)
    public Response downloadFileABC(){

         try{
              fileDownload.downloadABC();

         }catch(IOException e){

         }
          //Some code here that is common to the second method as well

    }

    @Path(/xyz)
     public Response downloadFileXYZ(){

         try{
              fileDownload.downloadXYZ();

         }catch(IOException e){
             //handle exception
         }
          //Some code here that is common to the first method as well

    }  
  }

class 是 JAX-RS 休息资源。正如您在上面的代码中所看到的,对于两种方法,除了 try 块中的内容之外,所有内容都是相同的。我们可以使用任何新的 JDK 8 将 fileDownload.downloadABC() 作为参数传递给私有方法的功能 ?

基本上,我正在寻找一些传递函数的方法 作为参数并让代码的其他部分相同。

可以这样做,只要 downloadABC()downloadXYZ() 方法与 [=14] 的 download() 方法具有相同的参数和 return 值=] 接口.

接口名称和接口方法可以任意选择。

@FunctionalInterface
interface DownloadMethod {
    public void doDownload() throws IOException;
}

class FileDownload {
    public void downloadABC() throws IOException {}
    public void downloadXYZ() throws IOException {}
}

class FileDownloadResource{

    @Inject
    private FileDownload fileDownload;

    @Path("/abc")
    public Response downloadFileABC(){
        return download(fileDownload::downloadABC);
    }

    @Path("/xyz")
    public Response downloadFileXYZ() {
        return download(fileDownload::downloadXYZ);
    }

    private Response download(DownloadMethod method){
        try{
            method.doDownload();
        }catch(IOException e){
            //handle exception
        }
        //Some code here that is common to both methods
    }
}

当然可以。您需要使用现有的功能界面或创建新的功能界面。正如你所期望的检查IOException,最好创建一个新的(你也可以使用Callable<Void>,但不太方便):

@FunctionalInterface
interface IORunnable {
    void run() throws IOException;
}

现在您可以创建通用请求处理程序私有方法:

public Response handleRequest(IORunnable r){
     try {
         r.run();
     } catch(IOException e){
         // handle exception
     }
     //Common code follows
}

并像这样使用它:

@Path("/abc")
public Response downloadFileABC(){
    return handleRequest(fileDownload::downloadABC);
}

或使用 lambda:

@Path("/abc")
public Response downloadFileABC(){
    return handleRequest(() -> fileDownload.downloadABC());
}