在 Java 中,是否可以声明一个永远不会变为空的字段?

Lam*_*bda 1 java null

假设我们定义了这个 Book 类,我们确保永远不会为 isbn 分配空值:

public class Book {

  private String isbn;

  public Book(String isbn) {
    setIsbn(isbn);
  }

  public void setIsbn(String isbn) {
    if (isbn == null) {
      throw new NullPointerException();
    }

    this.isbn = isbn;
  }

  public String getIsbn() {
    return this.isbn;
  }

}
Run Code Online (Sandbox Code Playgroud)

这可以防止创建 isbn 为 null 的 Book 对象,但是在创建具有非 null isbn 的 book 对象之后,我们可以通过反射修改该值并将其设置为 null。

无论如何(使用技巧或Java功能)是否可以防止Book的实例存在于其isbn为空的内存中?

注意:这个问题与Optionals无关。

Kay*_*man 6

从技术上讲,引用是可以为空的。即使您可以使用final来确保编译器不会让您留下变量null,您也可以使用反射来删除其最终性并将其设置为 null。

如果你算上反射,那么让我们说原生代码Unsafe或字节码检测等等。最后,内部表示允许空值,所以根据你要走多远,null如果你真的想要的话,会有一种方法来创建一个变量,除非你指定关于允许/可能的约束,例如 a 是否SecurityManager是涉及。

如果你问这个问题,因为你害怕,你的变量不是足够安全距离NullPointerExceptions,然后利用finalObjects.requireNonNull()以及良好的设计是不够的。


mtj*_*mtj 5

如果要排除反射,答案是否定的。

您唯一的选择是安装一个不允许反射的安全管理器,但是您希望您的代码在哪个敌对环境中运行?即便如此,启动 VM 的用户也可以添加一个代理,该代理可以操作字节码。

因此,就总体安全而言:不。