前几天,我正在查看一些代码,但遇到了:它不是错误,因为代码编译良好。这个“静态”代码块是什么?

#1 楼

这是一个静态初始化器。它是在加载类时执行的(确切地说,是初始化的,但通常不会注意到它们之间的区别)。
请注意,还有一些实例初始化程序,它们外观相同,只是它们没有static关键字。在创建对象的新实例时,这些操作会在构造函数中的代码之外运行。

评论


那么,为什么要使用非静态实例初始化程序而不是仅仅使用类构造函数(我可以认为这在匿名类中很有用)?

–乔里
13年7月19日在9:59

@Jori:一个常见的原因是,如果您有多个单独的构造函数(不只是“重定向”到单个规范的构造函数),并且您希望所有这些构造函数都有一些共同的初始化。

–约阿希姆·绍尔(Joachim Sauer)
13年7月19日在10:10

使代码更清晰,重复性更低。制定Java规范的人有时会使事情变得更加混乱,但是几乎总是有一个潜在的原因来说明为什么这样做。流操纵,有人吗?

– Mindwin
13年8月28日在19:31

执行顺序为:静态初始化程序,实例初始化程序,构造函数

–某处有人
2014年2月19日下午0:46

@SomeoneSomewhere虽然“实例初始化程序,构造函数”彼此相邻,但“静态初始化程序”可能早已执行。但是您说的对,最初的顺序是这样。实际上,它是“ SI,II,C,II,C,II,C,...”。

– glglgl
2014年8月31日在8:34



#2 楼

它是一个静态初始化器。它是在加载类时执行的,并且是放置静态变量的好地方。

来自http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html


类可以具有任意数量的静态初始化块,并且它们可以出现在类主体中的任何位置。运行时系统保证静态初始化块按在源代码中出现的顺序被调用。


如果您有一个带有静态查找映射的类,它可能看起来像这样

class MyClass {
    static Map<Double, String> labels;
    static {
        labels = new HashMap<Double, String>();
        labels.put(5.5, "five and a half");
        labels.put(7.1, "seven point 1");
    }
    //...
}


上面的静态字段无法使用labels = ...初始化。它需要以某种方式调用put-method。

评论


@aioobe我知道可能没有必要,但是如果没有暴露给静态初始化器,他们永远不会学到。此外,在某些情况下,不鼓励在声明中进行类成员初始化(我为之工作过的一些公司),建议在静态块或构造函数中(对于非静态成员)初始化它们。

– Mindwin
13年8月28日在19:29

我懂了。为什么不鼓励?我个人觉得声明中的成员初始化非常容易阅读和维护。我认为将它们强制进入构造函数可能不是一个好主意,特别是如果您有多个构造函数并且需要重复初始化的话。 (例如,如果您从ArrayList更改为LinkedList,则需要记住在多个位置进行更改。)

– aioobe
13年8月28日在20:18

如您所说,我们需要在每个构造函数中重复初始化代码。如果我们在实例初始化器中对其进行初始化,那将是最好的。

– Java技术
13-10-31在10:15

“运行时系统保证静态初始化块按它们在源代码中出现的顺序被调用。”静态块中的代码必须首先在类的构造函数之前执行

–阿诺
2015年8月7日在12:55



@PhilipRego,静态初始值设定项在某些情况下会很有用。例如,在匿名类中,没有构造函数可用于实例初始化。

– aioobe
18年2月15日在19:01

#3 楼

这是一个代码块,当类加载器加载该类时将执行该代码块。它旨在对类的静态成员进行初始化。

还可以编写看起来更陌生的非静态初始化器:

public class Foo {
    {
        // This code will be executed before every constructor
        // but after the call to super()
    }

    Foo() {

    }
}


评论


这看起来像一个普通的构造函数。

–Phantômaxx
15年6月14日在15:08

@DerGolem我认为他指的是普通构造函数上方的花括号。

– Saad
15年6月28日在16:55

甚至没有注意到...;)是的,很奇怪!

–Phantômaxx
15年6月28日在16:57

#4 楼

静态块可以用来表明程序也可以在没有主功能的情况下运行。

//static block
//static block is used to initlize static data member of the clas at the time of clas loading
//static block is exeuted before the main
class B
{
    static
    {
        System.out.println("Welcome to Java"); 
        System.exit(0); 
    }
}


评论


这仅在版本7之前适用,如果您要运行代码,则必须编写主代码。

– XFCC
2014年12月4日15:02

#5 楼

静态块在任何程序的生命周期中执行一次,
静态块的另一个属性是它在main方法之前执行。

#6 楼

静态块用于初始化代码,并将在JVM加载类时执行。请参考下面的链接,其中提供了详细说明。
http://www.jusfortechies.com/java/core-java/static -blocks.php

评论


您的链接不可用

–user7294900
18-10-4在8:50

@ user7294900检查此链接

–萨拉斯·加利梅卢(sarath galimelu)
18-10-25在19:00

#7 楼

是的,静态块用于初始化代码,它将在JVM启动执行时加载。 br />

评论


不是在启动JVM时,而是在加载类时。 JVM使用类加载机制,因此它会在使用类时加载类,而不是在JVM启动之前加载,永远不会加载

– 4lberto
15年5月26日在20:27