【问题标题】:Why this Consumer complaining compile time error?为什么这个消费者抱怨编译时错误?
【发布时间】:2019-02-16 08:15:04
【问题描述】:

我是 java8 的新手,我正在尝试编写模板方法设计模式,我正在为此使用 Consumer,但我不知道我做错了什么。

    package org.java.series.ds.cleancode;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Consumer;

public class Sample1 {
    public static void main(String[] args) throws Exception {
        OrderExporter exporter=new OrderExporter();
        Exporter exporter2=new Exporter();      
        exporter2.exportFiles("abc.csv", exporter::writeToCSV);

    }   

}

 class Exporter{    
    public  File exportFiles(String fileName,Consumer<Writer> consumer)throws Exception {
        File file=new File(fileName);
        try(FileWriter fileWriter=new FileWriter(file)){
            //writeContent(fileWriter);
            consumer.accept(fileWriter);
            return file;
        }catch (Exception e) {
            System.err.println(e);
            throw e;
        }
    }
}

class OrderExporter{
    public void writeToCSV(FileWriter fileWriter) throws IOException {
        fileWriter.write(String.format("%s,%d,%s", "kishan",29,"vns"));
    }
}

任何帮助都将不胜感激。

【问题讨论】:

  • Consumer&lt;Writer&gt; 想要将Writer 传递给某个函数,但是您提供了一个期望FileWriter 的方法,表面上看起来不错,但Java 正在尝试转换WriterFileWriter 这是它做不到的。我将writeToCSV 更改为期待Writer,它编译得很好。这对我来说更有意义,因为Exporter 决定了将使用Writer 的哪个实现,但只向Consumer 承诺提供Writer 的实例,我想这是有道理的.. . 我可能需要睡觉了:P
  • (1) 要传递一个与任何作家一起工作的消费者,需要将exportFiles 方法更改为接受Consumer&lt;? super Writer&gt;,并将writeToCSV 方法更改为接受&lt;T extends Writer&gt;,详情请参阅@987654321 @thread (2) 抛出异常的方法不能作为消费者传递,Java 8 Lambda function that throws exception?thread 上有详细说明抛出异常的方法如何作为消费者传递
  • @MadProgrammer 谢谢。

标签: java java-8 functional-java


【解决方案1】:

您不能使用期望 FileWriter 作为 Consumer&lt;Writer&gt; 的方法,因为这样的消费者需要接受任何类型的 Writer,但此方法只接受 FileWriter 或子类。

由于您在方法中使用 FileWriter,因此简单的答案是使用它作为绑定:

Consumer<FileWriter>

您可以使用下限使其更通用:

Consumer<? super FileWriter>

【讨论】:

  • 另外,Consumeraccept方法没有声明任何检查异常,所以目标方法一定不能声明抛出IOException
  • 或者您可以定义自己的Consumer 类,例如interface IOConsumer { void consume() throws IOException },并用它代替Consumer
  • 对于异常处理,最好更改接口(而不是将异常包装在UncheckedIOException中)。对于要消费的对象,我宁愿将目标方法writeToCSV 改为接受Writer,因为这里没有理由坚持FileWriter
猜你喜欢
  • 1970-01-01
  • 2016-11-01
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
  • 2012-09-12
  • 2012-03-28
  • 1970-01-01
相关资源
最近更新 更多