Java 8中的orElse方法未按预期工作

14
考虑以下方法,如果存在该字段,则返回该字段,否则递归调用本身,直到找到该字段:
private Field getField(Class<?> clazz, String p) {
    Optional<Field> field = Arrays.stream(clazz.getDeclaredFields())
            .filter(f -> p.equals(f.getName()))
            .findFirst();

    return field.isPresent() ? field.get() : getField(clazz.getSuperclass(), p);
}
虽然这个可以运作,但我想我可以将其缩短为:
private Field getField(Class<?> clazz, String p) {
    return Arrays.stream(clazz.getDeclaredFields())
            .filter(f -> p.equals(f.getName()))
            .findFirst()
            .orElse(getField(clazz.getSuperclass(), p));
}

但奇怪的是,.orElse 部分似乎总是被调用。

我错过了什么吗?


2
你是否意识到,如果该字段不存在,你最终会遇到一个“null”超类? - Holger
@Holger 是的,我知道,我只是为了简化代码而省略了它。 - helpermethod
1个回答

33

在调用方法之前,方法的参数总是被求值。您需要使用orElseGet方法,它接受一个Supplier作为参数,只有在Optional不存在时才会被调用:

private Field getField(Class<?> clazz, String p) {
    return Arrays.stream(clazz.getDeclaredFields())
            .filter(f -> p.equals(f.getName()))
            .findFirst()
            .orElseGet(() -> getField(clazz.getSuperclass(), p));
}

谢谢,完全忘了 getField 方法在执行之前会被调用。 - helpermethod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接