构建模式Intellij警告:从不使用方法的返回值

时间:2018-01-09 12:17:29

标签: java intellij-idea builder-pattern

我已经实现了一个简单的构建器模式 - 下面的代码。代码执行并运行,但构建器类中的每个'with ..'方法都会显示一条警告,其中“方法的返回值永远不会被使用”

public static class StreamParserBuilder{
    //optional - have defaults:
    private long spanLimit1 = 2000L;
    private long spanLimit2 = 100000L;
    private long spanLimit3 = 3000000L;
    private String[] coordinates = {"L1", "R2"};
    private String outputDirectory = System.getProperty("user.dir");
    private boolean isLastSteam = false;

    //required from the builder.
    private String[] args;
    private String inputFile;
    private String streamData;
    private boolean isPaired;

    public StreamParserBuilder(String[] args, String inputFile, String streamData, boolean isPaired){
        this.args = args;
        this.inputFile = inputFile;
        this.streamData = streamData;
        this.isPaired = isPaired;
    }

    public StreamParserBuilder withSpanLimit1(long spanLimit1){
        this.spanLimit1 = spanLimit1;
        return this;
    }

    public StreamParserBuilder withSpanLimit2(long spanLimit2){
        this.spanLimit2 = spanLimit2;
        return this;
    }

    public StreamParserBuilder withSpanLimit3(long spanLimit3){
        this.spanLimit3 = spanLimit3;
        return this;
    }

    public StreamParserBuilder withCoordinates(String[] coordinates){
        this.coordinates = coordinates;
        return this;
    }

    public StreamParserBuilder withOutputDirectory(String outputDirectory){
        this.outputDirectory = outputDirectory;
        return this;
    }

    public StreamParserBuilder isLastStream(boolean isLastSteam){
        this.isLastSteam = isLastSteam;
        return this;
    }

    public StreamParser build(){
        return new StreamParser(this);
    }

代码是否存在问题,也许我已经错误地实例化了.build()方法?我的StreamParser构造函数的代码:

private StreamParser(StreamParserBuilder streamParserBuilder){
    this.args = streamParserBuilder.args;
    this.inputFile = streamParserBuilder.inputFile;
    this.streamData = streamParserBuilder.streamData;
    this.spanLimit1 = streamParserBuilder.spanLimit1;
    this.spanLimit2 = streamParserBuilder.spanLimit2;
    this.spanLimit3 = streamParserBuilder.spanLimit3;
    this.coordinates = streamParserBuilder.coordinates;
    this.outputDirectory = streamParserBuilder.outputDirectory;
    this.isLastStream = streamParserBuilder.isLastSteam;
    this.isPaired = streamParserBuilder.isPaired;
}

有没有更好的方法来实现这个?如果代码没问题,会导致此警告的原因是什么?

编辑:使用StreamParserBuilder,调用withX函数:

 StreamParserBuilder streamBuilder = new StreamParserBuilder(args, inputFile, stream, isPaired);
        if (isSpanOneReplaced) streamBuilder.withSpanLimit1(spanLimit1);
        if (isSpanTwoReplaced) streamBuilder.withSpanLimit2(spanLimit2);
        if (isSpanThreeReplaced) streamBuilder.withSpanLimit3(spanLimit3);
        if (areCoordinatesReplaced) streamBuilder.withCoordinates(coordinates);
        if (isOutputDirectoryReplaced) streamBuilder.withOutputDirectory(outputDirectory);
        if (streamCount == streamData.size()) streamBuilder.isLastStream(true);
        StreamParser streamParser = streamBuilder.build();

5 个答案:

答案 0 :(得分:17)

"从不使用该方法的返回值"是来自Java | Declaration redundancy | Method can be void检查的警告。生成此警告是因为此方法返回的值从不在调用站点使用。可以通过使用@SuppressWarnings("UnusedReturnValue")注释课程或禁用Settings | Editor | Inspections中的检查来忽略警告。

答案 1 :(得分:0)

如果StreamParser对其构建器一无所知,那么更好的设计就是如此。我的意思是,构造函数StreamParser不将构建器作为参数。 更好的用法是:

StreamParserBuilder builder = new StreamParserBuilder(params)
                                    .withSpanLimit1(3)
                                    .withSpanLimit2(4);
StreamParser parser = builder.build();
// after that you can continue building object and create another parser
builder.withSpanLimit3(4);
StreamParser anotherParser = builder.build();

答案 2 :(得分:0)

构建器with的{​​{1}}方法是如此方法调用的原因可以链接:

return this;

在您的情况下,您忽略了调用代码中返回的值:

StreamParserBuilder streamBuilder = new StreamParserBuilder(args, inputFile, stream, isPaired)
    .withSpanLimit1(spanLimit1)
    .withSpanLimit2(spanLimit2)
    .withSpanLimit3(spanLimit3);

答案 3 :(得分:0)

在您的示例中,您并没有真正从构建器模式中受益。如果是罕见的用例,我就顺其自然,并忽略警告。但是,如果经常出现,将条件赋值直接包含到构建器中可能会有所帮助。 所以你可以写:

streamBuilder.conditionallyWithSpanLimit1(isSpanOneReplaced, spanLimit1)
    .conditionallyWithSpanLimit2(isSpanTwoReplaced, spanLimit2)
    // etc.

这将意味着复制所有构建器方法。

或者您可以引入流利的介词:

streamBuilder.when(isSpanOneReplaced).setSpanLimit1(spanLimit1)

如果您的构建器是接口,则实现起来非常简单。

public interface Builder {
    Builder setSpanLimit1(int value);
    Builder when(boolean condition);
    Object build();
}

如果您的when()方法不是build(),则可以通过以下方法调用返回代理,然后返回原始构建器。

答案 4 :(得分:0)

正如我发现的,Intellij IDEA 对 public 方法给出了这个警告,这是有问题的,因为可以从 Intellij IDEA 的其他包调用 public(或 protected)方法没有包含在它的分析中,如果您正在编写一个供其他项目使用的库 (JAR),这是可能的情况

幸运的是,configuring Settings > Editor > Inspections 可以禁用 Java > 声明冗余 > 方法可以无效 检查不是 唯一的修复。该检查也可以通过将最大报告方法可见性Public 更改为 Package-private 的选项进行配置。