为什么Optional 被声明为最终类?
我正在使用以下问题: 将Java 8的Optional与Stream :: flatMap一起使用,并希望将方法添加到自定义Optional
,然后检查它是否有效。
更准确地说,我想在我的CustomOptional
中添加一个stream()
,如果没有值,则返回一个空流,如果存在,则返回一个包含单个元素的流。
但是,我得出的结论是Optional
被声明为final。
为什么会这样? 有很多类没有被声明为final,我个人认为没有理由声明Optional
final。
作为第二个问题,为什么不能将所有方法都归结为最终,如果担心它们会被覆盖,并且让课程不是最终的?
根据Java SE 8 API文档的这个页面 , Optional
是一个基于值的类。 根据API文档的这一页,基于值的类必须是不可变的。
将Optional
所有方法声明为final将阻止方法被覆盖,但这不会阻止扩展类添加字段和方法。 扩展类并将字段与更改该字段值的方法一起添加将使该子类可变,从而允许创建可变的Optional
。 以下是如果Optional
不会被声明为final的话,可以创建的这样一个子类的示例。
//Example created by @assylias public class Sub extends Optional { private T t; public void set(T t) { this.t = t; } }
声明Optional
final会阻止创建类似上面的子类,因此保证Optional
始终是不可变的。
正如其他人所说,Optional是一个基于值的类,因为它是一个基于值的类,所以它应该是不可变的,需要它是最终的。
但我们错过了这一点。 基于值的类是不可变的主要原因之一是保证线程安全 。 使其不可变使其线程安全。 比如String或原始包装器,如Integer或Float。 由于类似的原因,他们被宣布为最
可能原因与String
为最终的原因相同; 也就是说,可以确保Optional
类的所有用户都确保他们收到的实例上的方法保持与他们总是返回相同值的契约。
虽然我们无法扩展Optional类,但我们可以创建自己的包装类。
public final class Opt { private Opt() { } public static final Stream filledOrEmpty(T t) { return Optional.ofNullable(t).isPresent() ? Stream.of(t) : Stream.empty(); } }
希望它可以帮助你。 很高兴看到反应!
- 线程“main”中的exceptionjava.lang.UnsatisfiedLinkError:java.library.path中没有opencv_java249
- 如何在Libgdx中调整sprite的大小?
- 将数据从servlet发送到applet:我该如何实现?
- 如何使用jndi显示ldap目录的所有对象类描述
- 为什么我会得到exceptionjava.lang.NoClassDefFoundError org / codehaus / groovy /?
- 在使用Spring MVC和Spring Security @PreAuthorize注释时,是否可以知道URL是否可访问?
- 在Java中与SQL Access数据库建立SQL连接时找不到合适的驱动程序
- JavaBean和Spring bean之间的区别
- 在哪里可以找到将regex应用于输出的Java Servletfilter?