Java:什么是静态{}?
有人能给我解释一下下面是什么吗?
public class Stuff
{
static
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch ( ClassNotFoundException exception )
{
log.error( "ClassNotFoundException " + exception.getMessage( ) );
}
...
}
这个 static { ...} 有什么作用?
我知道 C++ 中的静态变量,但那是静态块还是什么?
这东西什么时候才能执行?
Can someone explain me what the following is?
public class Stuff
{
static
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch ( ClassNotFoundException exception )
{
log.error( "ClassNotFoundException " + exception.getMessage( ) );
}
...
}
What does this static { ...} do?
I know about static variables from C++, but is that a static block or something?
When is this stuff going to get executed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
静态初始化块的主要用途是执行可能不适合在构造函数内进行的各种初始化操作,以便将构造函数和初始化程序结合在一起将新创建的对象置于完全一致的使用状态。
例如,与构造函数相反,静态初始值设定项不是继承的,并且仅在 JRE 加载和初始化类时执行一次。在上面的示例中,初始化完成后,类变量 foo 的值为 998877。
另请注意,静态初始化程序按照它们在源文件中文本出现的顺序执行。此外,在这些块之一内不能执行的操作还有许多限制,例如不能使用已检查异常、不能使用 return 语句或 this 和 super 关键字。
The primary use of static initializers blocks are to do various bits of initialization that may not be appropriate inside a constructor such that taken together the constructor and initializers put the newly created object into a state that is completely consistent for use.
In contrast to constructors, for example, static initializers aren't inherited and are only executed once when the class is loaded and initialized by the JRE. In the example above, the class variable foo will have the value 998877 once initialization is complete.
Note also that static initializers are executed in the order in which they appear textually in the source file. Also, there are a number of restrictions on what you can't do inside one of these blocks such as no use of checked exceptions, no use of the return statement or the this and super keywords.
我想补充一点,静态变量和静态初始化程序是按照类加载时出现的顺序执行的。因此,如果您的静态初始化程序依赖于某些静态变量,则必须在特定静态块之前对其进行初始化,例如,
在此示例中,
getJdbcDriver
将在静态初始化程序之前执行。此外,类中可能有超过 1 个静态初始值设定项。他们再次按照出场顺序被处决。我还想在这里提到实例初始值设定项的存在,因为第一次看到它们时确实会让人感到惊讶。它们看起来就像类体内的代码块,如下所示。
一般情况下,由于构造函数的原因,它们的使用有些不必要,但它们在实现 Java 版本的闭包时很有用。
I want to add that static variables and static initializers are executed in order of appearance at the time of class loading. So, if your static initializer relies on some static variable, it must be initialized before the particular static block, e.g.
In this example
getJdbcDriver
will get executed before static initializer. Also, there may be more than 1 static initializer in the class. Once again they are executed in order of appearance.I also want to mention the existence of instance initializers here, as they do come as surprise when seen for the first time. They look like a code block inside the class body, like this.
In general case their use is somewhat unnecessary, because of the constructor, but they are useful in implementing Java's version of closures.
每当第一次加载类时,都会执行静态初始化块。如果更高级别的操作第一次对相关类执行
Class#forName("yourpackage.YourClass")
或new YourClass()
,则可能会发生这种情况。巧合的是,像样的 JDBC 驱动程序内部也有类似的东西。也就是说,它们使用静态初始化块在
DriverManager
中注册自己:这样每当您执行
Class.forName("somepackage.ThisDriver")
时,您都将有效地注册驱动程序在DriverManager
中,以便您之后可以从中获取连接。The static initializer block get executed whenever the class is to be loaded for the first time. That can happen if something at higher level is doing a
Class#forName("yourpackage.YourClass")
or anew YourClass()
on the class in question for the first time.By a coincidence, the decent JDBC drivers also have something similar inside. They namely registers themselves in the
DriverManager
using a static initializer block:so that whenever you do a
Class.forName("somepackage.ThisDriver")
, you will effectively register the driver in theDriverManager
so that you can get a connection from it afterwards.除了上述内容之外,类构造函数和类初始值设定项的使用也存在细微差别。我们知道,构造函数通常用于初始化对象,如果我们有静态变量,则通常使用静态块以便在加载类时初始化它们。
当我们有静态变量和静态块时,首先初始化静态变量,然后再初始化块。
当类首次加载时,静态块在类构造函数之前初始化。
In addition to all above , there is a minute difference in using class constructor and class initializer. Constructor as we know that will be usually used to initialized the objects and if we have static variables then static block is usually used in order to initialize them when the class will be loaded.
When we have static variables and static block then static variables initialized first and then the block.
When class is first loaded, static block initializes before the class constructor.
静态初始化块
是一个普通的代码块
它用大括号 { } 括起来
它前面有 static 关键字
类可以有任意数量的静态初始化块
它们可以出现在类中的任何位置body
它们按照代码中出现的顺序调用
有一种替代静态初始化块的方法:
这种方式的优点是可以稍后调用静态方法来重新初始化类变量。
static initialization block
is a normal block of code
it is enclosed in braces { }
it is preceded by the static keyword
class can have any number of static initialization blocks
they can appear anywhere in the class body
they are called in the order of apperence in the code
There is an alternative to static initialization blocks:
The advantage of this approach is that the static method can be invoked later to reinitialize the class variable.
静态块称为 类静态初始值设定项 - 它在类第一次加载时运行(也是唯一一次运行[脚注])。
该特定块的目的是检查 MySQL 驱动程序是否位于类路径上(并抛出/log 错误(如果不是)。
[脚注] 静态块在每个加载类的类加载器中运行一次(因此,如果您有多个彼此不同的类加载器(例如,不委托),则每个加载器都会执行一次。
The static block is called a class static initializer - it gets run the first time the class is loaded (and it's the only time it's run [footnote]).
The purpose of that particular block is to check if the MySQL driver is on the classpath (and throw/log error if it's not).
[footnote] The static block run once per classloader that loads the class (so if you had multiple class loaders that are distinct from each other (e.g. doesn't delegate for example), it will be executed once each.