为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

POPMUISE 2021-09-12 10:39:24
查看 的源代码java.util.OptionalInt,一个可选的 int 由 anint value和 a 组成boolean isPresent。获得空可选整数的唯一方法是通过OptionalInt.empty()返回的方法,OptionalInt.EMPTY所有空可选整数的通用实例。如果是这种情况,那么为什么该isPresent()方法被实现为return isPresent而不是this == EMPTY通过摆脱该isPresent字段来减少内存使用量?
查看完整描述

2 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

这是一个实现选择,唯一可以给出明确答案的人是编写实现的人。

但很可能这是一种将代码的可读性、清晰度和可维护性置于内存微优化之上的选择。

担心布尔值在包装 int 的对象中占用的空间确实没有多大意义。如果该空间是相关的,OptionalInt考虑到对象头至少需要 8 个字节(在 32 位 JVM 上,在 64 位上更多),首先不应该使用an (或 Java)。

Java 不是用于编写内存受限的应用程序,而是用于编写易于维护的代码。并且isPresent()作为 getter for实现isPresent更容易阅读,在重构时更不容易出错,并且符合既定的 Java 编码实践。

它实际上确实增加了大小,因为该字段isPresent正好位于边界上,然后又添加了 7 个字节用于填充。


查看完整回答
反对 回复 2021-09-12
?
森林海

TA贡献2011条经验 获得超2个赞

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构造实例。


查看完整回答
反对 回复 2021-09-12
  • 2 回答
  • 0 关注
  • 130 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信