加载中...

  • Summary:支持 Java 类型上的nullness markers,以表明类型拒绝或故意允许null,是预览语言特性
  • Goals:增强 Java 引用类型以表达null引用是否为类型值所预期;支持不同nullness属性类型间的转换并伴随关于可能处理不当null值的警告;与传统 Java 代码兼容互操作,逐步采用新特性而不引入源或二进制不兼容性;确保拒绝null的变量在首次读取前初始化;在运行时强制拒绝null的类型;为运行时优化提供必要的元数据和完整性保证。
  • Non-Goals:不自动重新解释现有代码;不要求程序显式处理所有可能出现的null值;不更改原始类型;暂不将语言增强应用于标准库。
  • Motivation:Java 中变量类型String可能为null,有时作者希望变量始终持有String对象引用,有时期望null作为有意义的值,目前语言无法正式表达这种意图,导致混淆和错误。通过这些特性,可帮助开发者更早检测意外null,优化Value Class类型的变量,控制switch和类型模式中的nullness
  • Description

    • Nullness properties and markers:引用类型可表达nullnessFoo!null-restrictedFoo?nullable,默认Foonullnessunspecified。数组类型和参数化类型也可有nullness标记,未来可能有更方便的表达方式。
    • Field and array initialization:Java 中大多数变量使用前需初始化,传统上字段和数组组件有特殊处理,默认值为null,但对于null-restricted的字段和数组组件,必须在读取前初始化,有多种初始化方式。
    • Expression nullness and conversions:Java 编译器负责确定表达式的nullnessnullness conversion允许表达式在不同nullness间转换,有宽化和窄化转换,将int装箱和Integer拆箱的转换也受影响,直接将null字面量转换为null-restricted类型是编译时错误。
    • Run-time null checking:运行时,null值进行窄化nullness转换到null-restricted类型会抛出NullPointerException,一些窄化转换在源代码中不明显但在运行时会发生。
    • Nullness of type variables:类型变量类型可表达nullnessT!null-restrictedT?nullable,类型参数的nullness会影响 API 的替换nullness,但在泛型 API 的擦除实现中不能强制执行null限制。
    • Type arguments and bounds:类型参数可表达nullnessunchecked nullness conversions允许修改类型参数的nullness,可能导致警告,类型变量声明或通配符的边界也可有nullness标记。
    • Method overriding and type argument inference:确定方法是否有相同签名时忽略nullness,方法重写时返回类型需通过加宽引用转换等可转换,泛型方法中类型参数的nullness影响返回类型的推断。
    • Compiler warnings:使类型为null-restricted可能导致编译时错误,如字段或数组未初始化或尝试将null字面量转换为该类型,也可能有其他导致警告的情况。
    • Compilation & class file representation:大多数null标记在class文件中被擦除,Signature属性可包含nullness标记,NullRestricted属性可指示字段不允许null值,anewarray指令不支持null-restricted数组创建。
    • Core reflection:没有Foo!.classFoo?.class字面量,有新的RuntimeTypeAPI描述运行时数组和字段存储检查的类型,FieldArrayAPI也有相关支持。
    • Supplementary changes:传统反序列化与null-restricted字段和数组不兼容,javadoc生成的文档将包含nullness标记,java.lang.reflect.Typejavax.lang.modelAPI将在类型表示中编码nullness
  • Alternatives:Java 生态系统中的开发工具已实现自己的null编译时跟踪,但有局限性;其他编程语言在类型系统中跟踪nullness,Java 的特性需是可选的,便于逐步采用;运行时nullness强制可通过显式检查或标准 API 实现,但繁琐且无法直接应用于变量存储。
  • Dependencies:先决条件是灵活构造函数体(第二预览),未来工作包括空限制值类类型(预览)JEP 402:增强原始装箱(预览)、JVM 类和方法特化等,还可能有其他基于此 JEP 的增强,如应用nullness标记到标准 API 部分等。
阅读 12
0 条评论