【问题标题】:What is the difference between wrapping vars in a static code block and defining vars as static? [duplicate]在静态代码块中包装 var 和将 var 定义为静态有什么区别? [复制]
【发布时间】:2020-07-18 05:08:35
【问题描述】:

我是 Java 新手,我试图理解将变量定义为静态和在静态块中包含变量之间的区别。我制定了一个简化的例子来说明我的困惑:

import java.util.Properties;

public class Foo {
    static Properties myProps = new Properties();

    static {
        Properties myOtherProps = new Properties();
    }
    
    public static void bar()  {
        Foo.myProps.forEach(myProps::put); // Works just fine
        Foo.myOtherProps.forEach(myProps::put); // Throws cannot find symbol error
    }
}

静态变量myProps 似乎被bar() 方法正常引用,而myOtherProps 不能从该部分代码中引用。

在静态代码块中包装代码与将变量定义为静态之间有什么区别?

【问题讨论】:

  • 如果我被否决了,我至少可以理解为什么吗?
  • static {} 块不是一种无需为每个字段显式键入“静态”即可声明多个静态字段的机制。它是一个“静态初始化程序”,在类本身初始化时执行(在加载后但首次使用之前的某个时间发生)。您可以将任意代码放入初始化程序块中,但该代码的范围仅限于所述块。你得到的编译错误与你在一个方法中声明一个变量然后尝试在其他方法中访问它没有什么不同。

标签: java


【解决方案1】:

myProps 是一个类变量,几乎一直存在,可以引用为Foo.myProps,或者在类Foo 范围内仅引用myProps

myOtherProps 是一个局部变量,并且只存在于声明点直到包含声明的块的末尾。它只能被寻址为myOtherProps,并且只能在static 块的范围之外。

背景资料

如Java 语言规范4.12.3. Kinds of Variables 部分所述,有8 种变量。问题中的代码使用了其中的 2 个:

  1. 类变量是在类声明 (§8.3.1.1) 中使用关键字 static 声明的字段,或者在接口声明 (§9.3) 中使用或不使用关键字 static 声明的字段)。

    类变量在其类或接口准备好 (§12.3.2) 并初始化为默认值 (§4.12.5) 时创建。当类或接口被卸载时,类变量实际上不再存在 (§12.7)。

...

  1. 局部变量由局部变量声明语句 (§14.4) 声明。

    每当控制流进入块 (§14.2) 或 for 语句 (§14.14) 时,都会为立即包含在该块或 @ 中的局部变量声明语句中声明的每个局部变量创建一个新变量987654341@声明。

    局部变量声明语句可能包含初始化变量的表达式。然而,具有初始化表达式的局部变量在声明它的局部变量声明语句被执行之前不会被初始化。 (明确赋值规则 (§16 (Definite Assignment)) 防止局部变量的值在它被初始化或以其他方式赋值之前被使用。)当块或 for 语句的执行被执行时,局部变量实际上不再存在。完成。

【讨论】:

    【解决方案2】:

    这是因为变量仅在其作用域(和子作用域)中存在和可访问。

    在这种情况下,您将myOtherProps 定义在bar 的范围内,因此您无法访问它。

    解决办法:是在class范围内定义变量

    静态块用于类的静态初始化。 如果你想在静态上下文中发生很多事情,你应该做的是在父作用域中定义变量,然后在子作用域中访问它们:

    Properties myOtherProps;
    
    static {
        myOtherProps = new Properties();
    }
    
    public static void bar()  {
        Foo.myOtherProps.forEach(myProps::put); // will work
    }
        
    

    【讨论】:

      猜你喜欢
      • 2016-10-21
      • 2010-09-25
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      • 2013-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多