请结合http://blog.youkuaiyun.com/m1111121/article/details/8811757一起看
构造器初始化:
初始化顺序
局部变量中的基本数据类型是不会自动初始化话,但是全局变量就可以。
初始化顺序:静态数据(注意:static语句块 优先于 final static变量 优先于 static变量)于非静态数据(这个是按顺序来初始化的,有无final不影响)。变量初始化优先于构造器。
public class a {
static{
System.out.println("static语句块最先初始化");
}
final static int n=print("final static 其次初始化");
static int q=print("static最后初始化");
int m=print("一般非static的初始化");
final int mm=print("final 非static初始化");
static int print(String s){
System.out.println(s);
return 12;}
public static void main(String[] args){
a aa=new a();
}
}
static语句块最先初始化
final static 其次初始化
static最后初始化
一般非static的初始化
final 非static初始化
class Window{
Window(int n){
System.out.println("Window("+n+")");
}
}
class House{
Window w1=new Window(1);//before constructor
House(){
System.out.println("House()");
w3= new Window(33);//reinitialize w3
}
Window w2=new Window(2);//after constructor
void f(){System.out.println("f()");}
Window w3=new Window(3);//at end
}
public class Ini{
public static void main(String[] args){
House h=new House();
h.f();
}
}
结果:
静态数据的初始化
无论创建多少个对象,静态数据只占用一份储存区域。static关键字不能用于局部变量,只能作用于域。如果一个域是静态的基本类型域,且没有初始化,那么它就会获得基本类型的初值;如果它是一个对象的应用,那么它的初值就是null。静态数据只初始化一次
class Bowl{
Bowl(int n){
System.out.println("Bowl("+n+")");
}
void f1(int n){
System.out.println("f1("+n+")");
}
}
class Table{
static Bowl bowl1=new Bowl(1);
Table(){
System.out.println("Table");
bowl2.f1(1);
}
void f2(int n){
System.out.println("f2("+n+")");
}
static Bowl bowl2=new Bowl(2);
}
class Cupboard{
Bowl bowl3 =new Bowl(3);
static Bowl bowl4=new Bowl(4);
Cupboard(){
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int n){
System.out.println("f3("+n+")");
}
static Bowl bowl5=new Bowl(5);
}
public class a{
static Table table=new Table();
static Cupboard cupboard=new Cupboard();
public static void main(String[] args){
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
}
结果:要执行main()(静态方法),必须加载StaticInitialization类,然后静态域table和cupboard被初始化,这将导致它们对应的类也被加载,并且由于它们也都包含静态的Bowl对象,因此Bowl随后也被加载。所有类在main开始之前都被加载了(由输出可见,静态初始化只有在必要时才会进行,如果不创建Table对象,也不引用Table.b1或者Table.b2,那么静态的Bowl b1和b2永远不会被创建。只有在第一个Table对象被创建(或者第一次访问静态数据)的时候,它们才会被初始化。此后,静态对象不会再被初始化。)
class Bowl{
Bowl(int n){
System.out.println("Bowl("+n+")");
}
void f1(int n){
System.out.println("f1("+n+")");
}
}
class Table{
static Bowl bowl1=new Bowl(1);
Table(){
System.out.println("Table");
bowl2.f1(1);
}
void f2(int n){
System.out.println("f2("+n+")");
}
static Bowl bowl2=new Bowl(2);
}
class Cupboard{
Bowl bowl3 =new Bowl(3);
static Bowl bowl4=new Bowl(4);
Cupboard(){
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int n){
System.out.println("f3("+n+")");
}
static Bowl bowl5=new Bowl(5);
}
public class a{
//static Table table=new Table();
//static Cupboard cupboard=new Cupboard();
public static void main(String[] args){
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
//table.f2(1);
//cupboard.f3(1);
}
}
结果:
class Bowl{
Bowl(int n){
System.out.println("Bowl("+n+")");
}
void f1(int n){
System.out.println("f1("+n+")");
}
}
class Table{
static Bowl bowl1=new Bowl(1);
Table(){
System.out.println("Table");
bowl2.f1(1);
}
void f2(int n){
System.out.println("f2("+n+")");
}
static Bowl bowl2=new Bowl(2);
}
class Cupboard{
Bowl bowl3 =new Bowl(3);
static Bowl bowl4=new Bowl(4);
Cupboard(){
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int n){
System.out.println("f3("+n+")");
}
static Bowl bowl5=new Bowl(5);
}
public class a{
static Table table=new Table();
//static Cupboard cupboard=new Cupboard();
public static void main(String[] args){
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
table.f2(1);
//cupboard.f3(1);
}
}
结果:
显示的静态初始化
java允许将多个静态初始化动作组织成一个特殊的“静态字句”(有时也叫做“静态块”)。
public class Test{
static int i;
static {
i= 47;
}
}
与其他静态初始化动作一样,这段代码只执行一次,执行条件:首次生成这个类的一个对象时或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类的对象)
例如:
class Cup{
Cup(int n){
System.out.println("Cup("+n+")");
}
void f(int n){
System.out.println("f("+n+")");
}
}
class Cups{
static Cup cup1;
static Cup cup2;
static{
cup1=new Cup(1);
cup2=new Cup(2);
}
Cups(){
System.out.println("Cups()");
}
}
public class test{
//static Cups cups1=new Cups();//(2)
//static Cups cups2=new Cups();//(2)
public static void main(String[] args){
System.out.println("Inside main()");
Cups.cup1.f(99);//(1)
}
}
结果:
Cups.cup1.f(99)这里访问了Cups类的静态数据成员cup1,所以会初始化静态字句并产生Cup(1)、Cup(2)
class Cup{
Cup(int n){
System.out.println("Cup("+n+")");
}
void f(int n){
System.out.println("f("+n+")");
}
}
class Cups{
static Cup cup1;
static Cup cup2;
static{
cup1=new Cup(1);
cup2=new Cup(2);
}
Cups(){
System.out.println("Cups()");
}
}
public class test{
static Cups cups1=new Cups();//(2)
//static Cups cups2=new Cups();//(2)
public static void main(String[] args){
System.out.println("Inside main()");
Cups.cup1.f(99);//(1)
}
}
结果:
要执行main()(静态方法),必须加载StaticInitialization类,然后其静态域cups被初始化,那它对应的类也被初始化,结果是Cup(1)、Cup(2)、Cups(),当执行到Cups.cup1.f(99)时,由于静态只初始化一次,所以不再产生Cup(1)、Cup(2)。
class Cup{
Cup(int n){
System.out.println("Cup("+n+")");
}
void f(int n){
System.out.println("f("+n+")");
}
}
class Cups{
static Cup cup1;
static Cup cup2;
static{
cup1=new Cup(1);
cup2=new Cup(2);
}
Cups(){
System.out.println("Cups()");
}
}
public class test{
static Cups cups1=new Cups();//(2)
static Cups cups2=new Cups();//(2)
public static void main(String[] args){
System.out.println("Inside main()");
Cups.cup1.f(99);//(1)
}
}
结果: 这里也充分体现了静态初始化动作只执行一次
class Cup{
Cup(int n){
System.out.println("Cup("+n+")");
}
void f(int n){
System.out.println("f("+n+")");
}
}
class Cups{
static Cup cup1;
static Cup cup2;
static{
cup1=new Cup(1);
cup2=new Cup(2);
}
Cups(){
System.out.println("Cups()");
}
}
public class test{
static Cups cups1=new Cups();//(2)
static Cups cups2=new Cups();//(2)
public static void main(String[] args){
System.out.println("Inside main()");
//Cups.cup1.f(99);//(1)
}
}
结果: 大家自行分析下吧
非静态实例初始化
java中也有被称为 实例初始化 的类似于法。用来初始化每一个对象的非静态变量。例如:
class Mug{
Mug(int n){
System.out.println("Mug("+n+")");
}
}
public class Mugs{
Mug mug1;
Mug mug2;
{
mug1=new Mug(1);
mug2=new Mug(2);
System.out.println("mug1&mug2 initialized");
}
Mugs(){
System.out.println("Mugs()");
}
Mugs(int n){
System.out.println("Mugs(int)");
}
public static void main(String[] args){
System.out.println("Inside main");
new Mugs();
System.out.println("new Mugs() completed");
new Mugs(1);
System.out.println("new Mugs(1) completed");
}
}
结果: 这里非静态块初试化不止一次
补充个例子
class WithBlankFinalField {
}
public class AB {
//int i;
// WithBlankFinalField wfd;
public AB( int i){
i=100;//我们知道要使用一个变量对着对象的引用,必须先声明它们。方法参数int i就相当于初始化方法里面的i了,如果参数改为int m 就会报错。
System.out.println(i);
}
public AB( WithBlankFinalField wfd ){
wfd=new WithBlankFinalField() ;//情况和上面解释的一样
System.out.println(wfd);
}
public static void main(String args[]) {
AB ab=new AB(10);
AB abc=new AB(new WithBlankFinalField());
}
}
数组的初始化这里就省略。。。。