可选orElse意外抛出NPE;以null为值

时间:2018-11-22 10:51:20

标签: java java-8 optional

功能:

private static void printArray(int[] array, Optional<Integer> startIndex, Optional<Integer> endIndex) {
    for(Integer i = a.orElse(new Integer(0)); i<=endIndex.orElse(new Integer(array.length));i++) {
        System.out.print(array[i]+"  ");
    }
}

在传递像这样的值时:

printArray(arr1, null, null);

NPE被抛出。为什么Optional.orElse函数没有创建新的Integer对象?我检查了StackOverflow,但找不到从orElse抛出的NPE。我发现此行为是意外的。

欢迎提出所有建议。

3 个答案:

答案 0 :(得分:10)

您应该传递package main import ( "context" "log" "time" elastic "gopkg.in/olivere/elastic.v5" ) func main() { options := []elastic.ClientOptionFunc{ elastic.SetHealthcheck(true), elastic.SetHealthcheckTimeout(20 * time.Second), elastic.SetSniff(false), elastic.SetHealthcheckInterval(30 * time.Second), elastic.SetURL("http://127.0.0.1:9200"), elastic.SetRetrier(elastic.NewBackoffRetrier(elastic.NewConstantBackoff(5 * time.Second))), } client, err := elastic.NewClient(options...) if err != nil { panic(err) } // ensure index exist exists, err := client.IndexExists("my_index").Do(context.Background()) if err != nil { panic(err) } if !exists { if _, err := client.CreateIndex("my_index").Do(context.Background()); err != nil { panic(err) } } client.PutMapping().Index("my_index").BodyJson(map[string]interface{}{ "properties": map[string]string{ "name": "keyword", }, }).Do(context.Background()) // create new bulk processor from client bulkProcessor, err := elastic.NewBulkProcessorService(client). Workers(5). BulkActions(1000). FlushInterval(1 * time.Second). After(after). Do(context.Background()) // now the bulk processor can be reused for entire the app myDoc := struct { Name string }{ Name: "jack", } req := elastic.NewBulkIndexRequest() req.Index("my_index").Type("type").Id("my_doc_id").Doc(myDoc) // Use Add method to add request into the processor bulkProcessor.Add(req) // wait for sometime... time.Sleep(5 * time.Second) } func after(executionID int64, requests []elastic.BulkableRequest, response *elastic.BulkResponse, err error) { if err != nil { log.Printf("bulk commit failed, err: %v\n", err) } // do what ever you want in case bulk commit success log.Printf("commit successfully, len(requests)=%d\n", len(requests)) } 而不是Optional.empty()

null

如果传递printArray(arr1, Optional.empty(), Optional.empty()); ,则NPE将失败,因为您在null对象上调用了orElse(Java中的Optional没有特殊处理,它只是一个普通的对象)。 / p>

P.S。使用null代替OptionalInt

答案 1 :(得分:0)

private static void printArray(int[] array, Optional<Integer> startIndex, Optional<Integer> endIndex) {
    int from = Optional.ofNullable(startIndex).orElse(Optional.of(0)).orElse(0);
    int to = Optional.ofNullable(endIndex).orElse(Optional.of(array.length)).orElse(array.length);

    for (int i = from; i <= to; i++) {
        System.out.print(array[i] + "  ");
    }
}

答案 2 :(得分:0)

首先,您不应将可选参数作为参数传递给方法,如果您看到将可选参数传递给方法的代码-对其进行更改,请在调用方法的位置解开可选参数。 考虑this cheat sheet from Zeroturnaround

PS:只是为了好玩:我的建议是,如果您在此处使用可选选项,那么为什么不使用流? :)

public static void main(String[] args) {
    int[] array = new int[]{1, 2, 3, 4, 5};

    printArray(array, OptionalInt.of(0), OptionalInt.empty());
    System.out.println();
    printArray(array, OptionalInt.of(1), OptionalInt.empty());
    System.out.println();
    printArray(array, OptionalInt.of(1), OptionalInt.of(2));
    System.out.println();

}

private static void printArray(int[] array, OptionalInt startIndex, OptionalInt endIndex) {
    int startIdx = startIndex.orElse(0);
    int endIdx = endIndex.orElse(array.length);

    if (endIdx < startIdx)
        return;

    Arrays.stream(array).skip(startIdx).limit(endIdx).forEach(n -> System.out.print(n + " "));
}

它为我们提供了以下输出:

1 2 3 4 5 
2 3 4 5 
2 3