Java中的类字段初始化序列
以下两段代码的区别是什么:Java中的类字段初始化序列,java,initialization,Java,Initialization,以下两段代码的区别是什么: class B{ B(){} } //1) class A{ B b = new B(); } //2) class A{ B b; { b = new B(); } } 这两种方式的初始化有什么不同?另外,如果两个语句都在一个类中,那么它们的执行顺序是什么?为什么 编辑:添加更多说明: class C{ //1) int i = 5; //initializers block { i =7; } } 这
class B{
B(){}
}
//1)
class A{
B b = new B();
}
//2)
class A{
B b;
{
b = new B();
}
}
这两种方式的初始化有什么不同?另外,如果两个语句都在一个类中,那么它们的执行顺序是什么?为什么
编辑:添加更多说明:
class C{
//1)
int i = 5;
//initializers block
{
i =7;
}
}
这两条语句的执行顺序是什么?i的最终值是多少?更新新的更清晰的问题:
现在看来,我应该在我的问题中添加更多的文本。我
想知道两种情况下的执行顺序是什么
这些语句1和2位于同一个类中
变量
您对以下内容感兴趣:
private class Test {
public String field = new String("1");
{
field = new String("2");
}
}
Object obj = new Object()
首先,字段得到值1,然后调用构造函数,并执行编译时放置在ctor中的init块,因此字段的值为2
请参见此示例:
另请参见此问题和答案:
旧版本
我想你的意思是这样的:
private class Test {
public String field = new String("1");
{
field = new String("2");
}
}
Object obj = new Object()
或
花括号定义了给定可变寿命的范围
假设我们有以下示例:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
private static void checkObject(Object obj) {
if (obj == null)
System.out.println("Object is null");
else
System.out.println("Object is not null");
}
public static void main (String[] args) throws java.lang.Exception
{
Object obj;
{
obj = new Object();
checkObject(obj);
}
checkObject(obj);
}
}
输出为:
Object is not null
Object is not null
但如果我们将其改为:
{
Object obj = new Object();
checkObject(obj);
}
checkObject(obj);
它甚至不会编译并给出以下错误消息:
Main.java:22: error: cannot find symbol
checkObject(obj);
^
symbol: variable obj
location: class Ideone
1 error
第一个声明一个变量obj并在作用域内初始化它
因为它在声明之外,所以可以在作用域之后使用
如果它仅在范围内声明和初始化,则只能在范围内使用。
生存期绑定到范围
如果使用花括号初始化类字段
您可以使用多个语句来初始化它们
但您也可以简单地创建一个最终方法并调用该方法来初始化字段
花括号和字段初始化示例:
class A {
private String field;
{
StringBuilder builder = new StringBuilder("Text").append(value)
.append(" ")
.append(otherValue);
//make some computations
//append to builder
//add to field
field = builder.toString();
}
提示:
Java编译器将初始值设定项块复制到每个构造函数中。
因此,这种方法可用于在用户之间共享代码块
多个构造函数
见工作示例:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
private static void checkObject(Object obj) {
if (obj == null)
System.out.println("Object is null");
else
System.out.println("Object is not null");
}
public static void main (String[] args) throws java.lang.Exception
{
Object obj;
{
obj = new Object();
checkObject(obj);
}
checkObject(obj);
}
}
我认为这与以下几点有关: 初始化实例成员 通常,您会将初始化实例变量的代码放入 构造器。有两种方法可以替代使用构造函数 初始化实例变量:初始化程序块和final方法 实例变量的初始值设定项块看起来就像静态的 初始值设定项阻止,但不包含static关键字:
{
// whatever code is needed for initialization goes here
}
Java编译器将初始值设定项块复制到每个构造函数中。
因此,这种方法可用于在用户之间共享代码块
多个构造函数
基本上,这意味着括号之间的所有实例变量都将为所有构造函数初始化。即使您的类没有多个构造函数
class A{
B b;
int index;
String result;
{
b = new B();
index = 0;
}
public A(int temp){
// nothing
}
public A(int temp, String test){
this.result = test;
}
public int getIndex(){
return index;
}
}
添加了具有多个构造函数的示例
class A{
B b;
int index;
String result;
{
b = new B();
index = 0;
}
public A(int temp){
// nothing
}
public A(int temp, String test){
this.result = test;
}
public int getIndex(){
return index;
}
}
在这里使用哪个构造函数并不重要,因为括号之间的初始化被复制到两个构造函数中。a、 getIndex将始终返回“0”,因为您知道在实例化类时会调用构造函数。在JAVA中,所有类都有顶级类作为对象。现在,无论何时我们为您的案例调用任何类的构造函数,它都会导致我们调用第一个超级引导对象的构造函数 现在在示例1中,变量b在类本身中声明并初始化。因此,在类A的构造函数被执行之前,变量b被初始化,也就是说,在公共A中编写的所有代码都将在b被初始化之后执行 在示例2中,变量b在类中声明,但在A的构造函数中初始化。如果在行b=新b之前有一些代码;首先执行该代码,然后初始化b 请参见下面的示例:
Class A{
B b = new B();
public A(){
b == null; //FALSE as it has been already initialised.
}
}
但是
您可以发布可编译的代码吗?是的,您的代码甚至不会像现在这样编译。您编写的代码不是有效的java代码。请编辑相同的内容并再次发布。对于案例2,您没有为任何内容分配b,而是为实例初始值设定项创建了一个单独的局部变量b。如果你的意思是b=新的b;那么第一个和第二个示例是等效的。在这两个示例中,成员变量的初始化是在隐式创建的无参数构造函数A中对super的隐式调用之后执行的。@W vd L,我知道初始化器块。我想知道的是,如果1我们在任何块之外创建obejectin类声明,2我们在初始值设定项块中创建一个对象,会有什么不同。。init块用于在使用多个重载构造函数时简化代码。让我再举一个例子