Java 静态初始值设定项块与常规静态初始化之间的差异

Java 静态初始值设定项块与常规静态初始化之间的差异,java,static,initialization,Java,Static,Initialization,正如标题所说,两者之间到底有什么区别 public static String myString = "Hello World!"; 及 除了结构之外,还有什么重要的区别吗?在第一个示例中,变量在同一行上声明和初始化。在第二个示例中,首先声明变量,然后初始化。在第二种情况下,您可以在到达所讨论的初始化块之前进行任意数量的其他静态变量和块初始化。考虑这种情况: public static String myString = "Hello World!"; public static String

正如标题所说,两者之间到底有什么区别

public static String myString = "Hello World!";


除了结构之外,还有什么重要的区别吗?

在第一个示例中,变量在同一行上声明和初始化。在第二个示例中,首先声明变量,然后初始化。在第二种情况下,您可以在到达所讨论的初始化块之前进行任意数量的其他静态变量和块初始化。考虑这种情况:

public static String myString = "Hello World!";
public static String yourString = myString;
static {
    System.out.println(myString);
    System.out.println(yourString);
}
vs:

第一个示例的输出:

Hello World Hello World 你好,世界 你好,世界 第二个示例的输出:

Hello World null 你好,世界 无效的
就你的例子来说,没有区别。但正如你所见

public static String myString = "Hello World!";
只能接受表达式来初始化变量。但是,在a(JLS 8.7)中,可以执行任意数量的语句。例如,可以这样做:

static
{
    myString = "Hello";
    myString += " ";
    myString += "World";
}

对于你的例子来说,显然没有必要这样做,但是变量的初始化可能不仅仅是一个表达式,也许是许多语句,因此Java制造了静态初始值设定项。

使用静态块,您可以更改不同于声明顺序的初始化顺序。

静态变量存储一个值,该值在定义它的类的所有实例(或非实例)之间共享

静态块是第一次加载类时执行的代码段

“关于作用域,静态块只能在同一类中访问”,“而静态变量可以从任何类访问”

静态初始化程序块和常规静态初始化之间的差异

在变量初始化的情况下,两者是相同的

但如果我们只想和数据库连接一次,或者任何您想加载一次的操作。然后在静态块中编写代码,因为无论您创建了多少个该类型的对象,在加载第一个类时它只执行一次

编辑:

也可以构造类似的块:

{
    // Do Something...
}
例如:

public class Demo {

    static{
        System.out.println("Static");
    }

    {
        System.out.println("Non-static block");
    }

    public static void main(String[] args) {
        Demo demo = new Demo();
        Demo demo2 = new Demo();
    }
}
输出:

静止的

非静态块


非静态块

静态{…}块为您提供了一个在字段声明中做不到的事情的机会

例如,您可以填写地图的一些详细信息:

private static final Map<String, String> data = new HashMap<String, String>();

static {
    data.put("A", "Hello");
    data.put("B", "There");
    data.put("C", "You");
}

通常,静态变量的值在定义它的类的所有实例(或非实例)之间共享,其中静态块是第一次加载类时执行的代码段。功能上没有区别。

要继续Scott Stanchfield所写的内容,您可以使用
Collections.unmodifiableXXX()
方法来确保安全,尽管像Google Guava这样的库可能会减少这种必要性。考虑:

public static final Map<String, String> CAPITALS;
static {
    Map<String, String> map = new HashMap<>(); //Java 7.
    map.put("NY", "Albany");
    map.put("MD", "Annapolis");
    map.put("VA", "Richmond");
    map.put("CT", "Hartford");
    // 46 more states
    CAPITALS = Collections.unmodifiableMap(map);
}
公共静态最终地图首都;
静止的{
Map Map=newhashmap();//Java 7。
地图放置(“纽约”、“奥尔巴尼”);
地图放置(“MD”、“安纳波利斯”);
地图放置(“弗吉尼亚州”、“里士满”);
地图放置(“CT”、“Hartford”);
//又有46个国家
大写=集合。不可修改地图(map);
}
当然,拥有一个52行的静态块可能会迷失方向,因此您可以取而代之的是使用静态块并将其转换为静态方法

public static final Map<String, String> CAPITALS = capitals();
private static Map<String, String> capitals() {
    Map<String, String> map = new HashMap<>(); //Java 7.
    map.put("NY", "Albany");
    map.put("MD", "Annapolis");
    map.put("VA", "Richmond");
    map.put("CT", "Hartford");
    // 46 more states
    return Collections.unmodifiableMap(map);
}
公共静态最终地图大写=大写();
私有静态映射资本(){
Map Map=newhashmap();//Java 7。
地图放置(“纽约”、“奥尔巴尼”);
地图放置(“MD”、“安纳波利斯”);
地图放置(“弗吉尼亚州”、“里士满”);
地图放置(“CT”、“Hartford”);
//又有46个国家
返回集合。不可修改映射(map);
}
不同之处在于风格。您可以只使用数据库表

public class Foo {
    private static final Person person;

    static {
        InputStream personData = Foo.class.getResourceAsStream("something.txt");
        person = new Person(personData);
    }
    ...
}
public static final Map<String, String> CAPITALS;
static {
    Map<String, String> map = new HashMap<>(); //Java 7.
    map.put("NY", "Albany");
    map.put("MD", "Annapolis");
    map.put("VA", "Richmond");
    map.put("CT", "Hartford");
    // 46 more states
    CAPITALS = Collections.unmodifiableMap(map);
}
public static final Map<String, String> CAPITALS = capitals();
private static Map<String, String> capitals() {
    Map<String, String> map = new HashMap<>(); //Java 7.
    map.put("NY", "Albany");
    map.put("MD", "Annapolis");
    map.put("VA", "Richmond");
    map.put("CT", "Hartford");
    // 46 more states
    return Collections.unmodifiableMap(map);
}