class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
data = new ArrayList<Object>();
name = "Default name";
userFriendlyName = "Default user friendly name";
}
public B(String name) {
data = new ArrayList<Object>();
this.name = name;
userFriendlyName = name;
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
public class Test {
static int staticVariable;
int nonStaticVariable;
// Static initialization block:
// Runs once (when the class is initialized)
static {
System.out.println("Static initalization.");
staticVariable = 5;
}
// Instance initialization block:
// Runs each time you instantiate an object
{
System.out.println("Instance initialization.");
nonStaticVariable = 7;
}
public Test() {
System.out.println("Constructor.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
10条答案
按热度按时间webghufk1#
初始化块在初始化类时和调用构造函数之前执行。它们通常放置在支架中的构造函数上方。在你的课堂上完全没有必要包括他们。
它们通常用于初始化引用变量。这一页解释得很好
nszi6y052#
输出:
zf9nrax13#
除了前面的回答中所说的以外,还可以使用积木
synchronized
.. 从来没有觉得我需要用它,但是,它就在那里5cnsuln74#
想补充@aioobe的答案吗
执行顺序:
超类的静态初始化块
类的静态初始化块
超类示例初始化块
超类的构造函数
类的示例初始化块
类的构造函数。
另外要记住几点(第一点是重复@aioobe的答案):
静态初始化块中的代码将在类加载时执行(是的,这意味着每个类加载只执行一次),在类的任何示例被构造之前和任何静态方法被调用之前。
示例初始化块实际上是由java编译器复制到类的每个构造函数中的。所以每次示例初始化块中的代码在构造函数中的代码之前执行。
hsgswve45#
这个问题还不完全清楚,但这里简要介绍了初始化对象中数据的方法。假设您有一个类a,它包含一个对象列表。
1) 在字段声明中输入初始值:
2) 在构造函数中指定初始值:
它们都假设您不想将“data”作为构造函数参数传递。
如果将重载构造函数与上述内部数据混合使用,事情会变得有点棘手。考虑:
请注意,有很多重复的代码。您可以通过使构造函数相互调用来解决此问题,也可以使用每个构造函数调用的私有初始化方法:
或
两者(或多或少)是等价的。
我希望这能给您一些关于如何初始化对象中的数据的提示。我不会谈论静态初始化块,因为这可能是目前有点先进。
编辑:我将您的问题解释为“如何初始化示例变量”,而不是“初始化程序块如何工作”,因为初始化程序块是一个相对高级的概念,从问题的语气来看,您似乎在问更简单的概念。我可能错了。
3yhwsihp6#
再加上@aioobe和@biman tripathy的优秀答案。
静态初始值设定项相当于静态上下文中的构造函数。这是设置静态环境所需要的。示例初始值设定项最适合匿名内部类。
类中也可以有多个初始值设定项块
当我们有多个初始值设定项块时,它们会按它们出现的顺序执行(实际上是由jvm复制到构造函数中)
初始值设定项块的顺序很重要,但与构造函数混合的初始值设定项块的顺序并不重要
抽象类也可以同时具有静态和示例初始值设定项块。
代码演示-
创建的示例
SupersonicAircraft
将按以下顺序生成日志5cnsuln77#
首先,有两种类型的初始化块:
示例初始化块,以及
静态初始化块。
此代码应说明它们的用法以及它们的执行顺序:
印刷品:
如果您希望运行某些代码,而不管使用哪个构造函数,或者希望对匿名类执行某些示例初始化,则示例初始化块非常有用。
xkftehaa8#
示例代码,在这里被批准作为一个答案是正确的,但我不同意它。它没有显示正在发生的事情,我将向您展示一个很好的示例来了解jvm的实际工作方式:
在开始评论源代码之前,我将对类的静态变量做一个简短的解释:
首先,它们被称为类变量,它们属于类而不是类的特定示例。类的所有示例都共享这个静态(类)变量。每个变量都有一个默认值,具体取决于基元或引用类型。另一件事是,当您在类的某些成员(初始化块、构造函数、方法、属性)中重新分配静态变量时,这样做是在更改静态变量的值,而不是针对特定示例,而是针对所有示例更改它。为了总结静态部分,我将说,类的静态变量不是在您第一次示例化类时创建的,而是在您定义类时创建的,它们存在于jvm中,不需要任何示例。因此,从外部类(未定义静态成员的类)正确访问静态成员的方法是,先使用点后面的类名,然后使用要访问的静态成员(模板:
<CLASS_NAME>.<STATIC_VARIABLE_NAME>
).现在让我们看看上面的代码:
入口点是主方法-只有三行代码。我想参考目前被批准的例子。根据它,在打印“静态初始化块”之后必须打印的第一件事是“初始化块”,我不同意,非静态初始化块不是在构造函数之前调用的,它是在定义初始化块的类的构造函数的任何初始化之前调用的。当您创建一个对象(类的示例)时,首先涉及类的构造函数,然后当您输入构造函数时,调用的第一部分是隐式(默认)超级构造函数或显式超级构造函数,或者显式调用另一个重载构造函数(但在某个点上,如果存在一个重载的链)构造函数,最后一个构造函数隐式或显式地调用超级构造函数)。
有一个对象的多态创建,但是在进入类b及其主方法之前,jvm初始化所有类(静态)变量,然后通过静态初始化块(如果有的话),然后进入类b并开始执行主方法。它转到类b的构造函数,然后立即(隐式)调用类a的构造函数,使用多态性在类a的构造函数体中调用的方法(重写方法)是在类b中定义的方法,在这种情况下,在重新初始化之前使用名为instancevariable的变量。关闭类b的构造函数后,线程返回到类b的构造函数,但它首先进入非静态初始化块,然后再打印“constructor”。为了更好地理解如何用ide调试它,我更喜欢eclipse。
5ktev3wc9#
很好的答案,艾奥比多加了几分
这给
这就像陈述显而易见的东西,但似乎更清楚一点。
fykwrbwg10#
initializer块包含在创建示例时始终执行的代码。它用于声明/初始化类的各种构造函数的公共部分。
初始化构造函数和初始化程序块的顺序无关紧要,初始化程序块总是在构造函数之前执行。
如果我们想对一个类的所有对象执行一次代码呢?
我们在java中使用静态块。