Java 何时使用空白的最终变量合适?

Java 何时使用空白的最终变量合适?,java,final,Java,Final,我在看另一个关于final变量的文章,注意到您可以声明final变量而无需初始化它们(变量)。是否有这样做的原因,以及什么时候这样做有利?这对于创建不可变对象很有用: public class Bla { private final Color color; public Bla(Color c) {this.color = c}; } Bla是不可变的(一旦创建,它就不能更改,因为颜色是最终的)。 但是,您仍然可以通过使用各种颜色构建BLA来创建各种BLA 另见示例 编辑

我在看另一个关于final变量的文章,注意到您可以声明final变量而无需初始化它们(变量)。是否有这样做的原因,以及什么时候这样做有利?

这对于创建不可变对象很有用:

public class Bla {
    private final Color color;

    public Bla(Color c) {this.color = c};

}
Bla是不可变的(一旦创建,它就不能更改,因为颜色是最终的)。 但是,您仍然可以通过使用各种颜色构建BLA来创建各种BLA

另见示例

编辑

也许值得一提的是,“空白最终版本”在Java中有一个非常特殊的含义,这似乎在注释中造成了一些混乱-参见:

空final是其声明缺少初始值设定项的final变量


然后必须在构造函数中指定该空的最终变量。

如果在插入对象之前不知道该值是什么,则可以这样做,只需在其构造函数中指定一个值即可

这是您制作的方式,并在生成器模式中使用

class Builder{
    final BuilderContext context;

    private Builder(BuilderContext context){
        this.context=context;
    }       

    public static Builder New(){
        return new Builder(new BuilderContext());
    }
注意,您可以声明
final
变量,而无需初始化它们


您必须稍后对其进行初始化(例如在构造函数中),以便它不会保持为空。

在创建对象之前,必须为类的最终属性指定一个值。所以最后一个可以赋值的点是构造函数

这经常被用来做广告

来自

Java1.1中引入的空白final是一个final变量,其声明缺少初始值设定项。空白决赛只能分配一次,并且在分配时必须取消分配。为了做到这一点,Java编译器运行一个流分析,以确保对于一个空白的最终变量的每个赋值,在赋值之前该变量肯定是未赋值的;否则会发生编译时错误


一般来说,java编译器将确保在分配一个值之前不使用空白最终值,并且一旦分配了值,现在的最终变量就不能重新分配另一个值。

空白的最终变量必须在构造函数中被分配为“某处”。一个相当复杂的例子:

public class Test {
    final int sign;
    public Test(String upDown) {
        if (upDown.equals("up")) {
            sign = +1;
        } else {
            sign = -1;
        }
    }
}

一种情况可能是,您有一个字段要声明为final,但其赋值可能会引发异常,并且您希望在发生这种情况时能够采取操作:

class A {
  final URLConnection conn;
  A(String url) {
    try {
      this.conn = new URL(url).openConnection();
    } catch (IOException | MalformedURLException e) {
      // Maybe this isn't fatal, so just handle the Exception
      // here and move on happily
    }
  }
}

在方法中使用一个空白的final变量,以显示所有使用该变量的代码路径只分配该变量一次(或引发异常)。Java编译器将保证在使用前分配一个空白的最终变量

某些方法中的示例代码:

  final Foo foo;
  if (condition1()) {
    foo = makeFoo(1);
  } else if (condition2()) {
    throw new BarException();
  } else {
    foo = makeFoo(-1);
  }
  ...
  blahBlahBlah(foo);
使用空白的final变量告诉代码的下一个读者,编译器保证在调用blahBlahBlah(foo)之前有人分配了foo


该问题询问“空白最终变量”。“空白最终字段”的讨论是另一种讨论,它本身就很有趣。

我发现它们对于派生状态的方法非常有用。它提供了一个干净的执行路径,并确保状态变量被赋值一次且仅赋值一次。例如:

public boolean isEdible() {
    final boolean edible;

    if (vegetable) {
        edible = true;
    } else if (animal) {
        if (vegetarian) {
            edible = false;
        } else {
            edible = true;
        } 
    }
    System.out.println("Is edible: " + edible);
    return edible;
}

几乎从来没有。空白期末考试什么也做不了。它们是永远不会有任何有意义的值的变量。任何值得一试的java编译器都会给你一个警告和/或错误。当你想在构造函数中初始化它(基于一些构造函数参数)时,这会很有用。@sshannin在构造函数中声明final和initialization不是空final,这是一个final变量的声明和初始化。@Hans这正是空白final的定义。@Hans:“空白
final
是一个
final
变量,其声明中缺少初始值设定项。”是的。根据维基百科的引文,这就是“空白定稿”所指的内容。@LouisWasserman,我没有意识到维基百科描述了它。我已经给维基添加了一个参考,但是,你的“空白最终”表明维基不是获取知识的最佳场所。;-。等等,什么?OP链接的问题的公认答案包括一个维基百科链接,该链接的引用与您的答案一致。我认为blank final不是官方命名,但正如assylias引用的,未初始化的final字段被称为blank final。我想我说的对,您不能这样做。:)我不知道这件事+1编译器会抱怨将
new
作为方法名。new()方法不应该声明为静态的吗@约翰肯
public boolean isEdible() {
    final boolean edible;

    if (vegetable) {
        edible = true;
    } else if (animal) {
        if (vegetarian) {
            edible = false;
        } else {
            edible = true;
        } 
    }
    System.out.println("Is edible: " + edible);
    return edible;
}