web-dev-qa-db-ja.com

ビルドパターンIntellij警告:メソッドの戻り値は使用されません

簡単なビルダーパターンを実装しました-以下のコード。コードは実行されて実行されますが、ビルダークラスのすべての「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;
}

これを実装するより良い方法はありますか?コードに問題がない場合、この警告の原因は何ですか?

編集:withX関数を呼び出すStreamParserBuilderの使用法:

 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();
10
Sam

「メソッドの戻り値は使用されません」は、_Java | Declaration redundancy | Method can be void_検査からの警告です。この警告は、このメソッドによって返された値が呼び出しサイトで使用されることはないために生成されます。クラスに@SuppressWarnings("UnusedReturnValue")で注釈を付けるか、_Settings | Editor | Inspections_で検査を無効にすることにより、警告を無視することができます。

22
Bas Leijdekkers

あなたの例では、あなたはビルダーパターンから本当に利益を得ていません。それがまれなユースケースである場合は、そのままにし、警告は無視します。ただし、頻繁に発生する場合は、条件付き割り当てをビルダーに直接含めると効果的です。だからあなたはどちらかを書くかもしれません:

_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()メソッドが次のメソッド呼び出しをパスして、元のビルダーを返すことにより、プロキシを返すことができます。

0
Ondřej Fischer

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();
0
niemar

ビルダーのwithメソッドreturn this;は、メソッド呼び出しをチェーンできるようにするためです。

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

あなたのケースでは、呼び出しコードの戻り値を無視しています:

// returns StreamBuilderParses, which you're ignoring
if (isSpanOneReplaced) streamBuilder.withSpanLimit1(spanLimit1);
0
Madbreaks