猿问

OptionalInt.isPresent 字段的用途是什么?

查看 的源代码java.util.OptionalInt,一个可选的 int 由 anint value和 a 组成boolean isPresent。获得空可选整数的唯一方法是通过OptionalInt.empty()返回的方法,OptionalInt.EMPTY所有空可选整数的通用实例。

如果是这种情况,那么为什么该isPresent()方法被实现为return isPresent而不是this == EMPTY通过摆脱该isPresent字段来减少内存使用量?


POPMUISE
浏览 131回答 2
2回答

绝地无双

这是一个实现选择,唯一可以给出明确答案的人是编写实现的人。但很可能这是一种将代码的可读性、清晰度和可维护性置于内存微优化之上的选择。担心布尔值在包装 int 的对象中占用的空间确实没有多大意义。如果该空间是相关的,OptionalInt考虑到对象头至少需要 8 个字节(在 32 位 JVM 上,在 64 位上更多),首先不应该使用an (或 Java)。Java 不是用于编写内存受限的应用程序,而是用于编写易于维护的代码。并且isPresent()作为 getter for实现isPresent更容易阅读,在重构时更不容易出错,并且符合既定的 Java 编码实践。它实际上确实增加了大小,因为该字段isPresent正好位于边界上,然后又添加了 7 个字节用于填充。

森林海

如OptionalInt.empty()方法文档中所述:尽管这样做可能很诱人,但请避免通过与==返回的实例进行比较来测试对象是否为空OptionalInt.empty()。不能保证它是单例。相反,使用#isPresent().事实上,以下测试通过了:import static org.junit.jupiter.api.Assertions.assertFalse;import static org.junit.jupiter.api.Assertions.assertNotSame;import static org.junit.jupiter.api.Assertions.assertSame;import java.lang.reflect.InvocationTargetException;import java.util.OptionalInt;import org.junit.jupiter.api.Test;class Tests {    @Test    void test() {        var empty = OptionalInt.empty();        assertSame(empty, empty);        var anotherEmpty = fabricateEmpty();        assertFalse(anotherEmpty.isPresent());        assertNotSame(empty, anotherEmpty);    }    private OptionalInt fabricateEmpty() {        try {            var constructor = OptionalInt.class.getDeclaredConstructor();            constructor.setAccessible(true);            return constructor.newInstance();        } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {            throw new RuntimeException(e);        }    }}虽然看起来有些人为设计,但许多流行的框架使用反射或Unsafe构造实例。
随时随地看视频慕课网APP

相关分类

Java
我要回答