Gần đây, khi làm việc với Java 8 suối, tôi tình cờ gặp một NullPointerException
vào một hoạt động giảm trong khi làm việc với các trường hợp kiểm tra sau:NPE vào hoạt động java giảm hoạt động
private static final BinaryOperator<Integer> sum = (a, b) -> {
if (a == null) return b;
if (b == null) return a;
return Integer.sum(a, b);
};
List<Integer> s = new ArrayList<>();
s.add(null);
s.add(null);
s.add(null);
Integer i = s.stream().reduce(sum).orElse(null);
// throws NPE
Integer i = s.stream().reduce(sum).orElse(2);
// throws NPE
Integer i = s.stream().reduce(null,(a, b)->null);
// returns a value i.e null
Hoặc cách khác:
Integer i = s.stream().filter(Objects::nonNull).reduce(Integer::sum).orElse(null);
// returns a value i.e null
Khi kiểm tra hoạt động giảm, tôi đã xem qua lớp này thực hiện thao tác giảm:
class ReducingSink implements AccumulatingSink<T, Optional<T>, ReducingSink> {
private boolean empty;
private T state;
public void begin(long size) {
empty = true;
state = null;
}
@Override
public void accept(T t) {
if (empty) {
empty = false;
state = t;
} else {
state = operator.apply(state, t);
}
}
@Override
public Optional<T> get() {
return empty ? Optional.empty() : Optional.of(state);
}
@Override
public void combine(ReducingSink other) {
if (!other.empty)
accept(other.state);
}
}
Trong đoạn mã trên, bạn thấy rằng phương thức get()
trả về giá trị tùy chọn nếu boolean empty
là sai và trong trường hợp của tôi giá trị là false nhưng state
là không, vì vậy Optional.of(null)
ném một NullPointerException
. Trong trường hợp của tôi, tôi có một toán tử nhị phân cho phép null
.
Vì vậy, tôi nghĩ rằng mã
return empty ? Optional.empty() : Optional.of(state);
nên được thay đổi để
return empty || state == null ? Optional.empty() : Optional.of(state);
Như điều hành nhị phân của tôi (trong đó có nhiệm vụ giảm) và không quan trọng với null
.
Làm thế nào về 'Optional.ofNullable'? Dù sao ví dụ của bạn trông không đúng kể từ khi bạn đang sử dụng 'Danh sách' với 'BinaryOperator '. –
Pshemo
@Pshemo 'ReducingSink' là một lớp jdk nội bộ – Eugene
Dù sao - @Pshemo là đúng - ví dụ không biên dịch rất tốt :-) –