java中init方法是怎样生成的?

文章目录

  • 1 对象的三种初始化方法
  • 2 init的结构:
  • 3 this()和super()上不能try……catch
  • 4 遇到new时
  • 5 不能这样提前引用。会拒绝编译
  • 6 提前引用的两种方式
  • 7 参考文献


一个类可以有多个方法,但只能有一个方法。需要注意的是方法只初始化本类中的实例变量

1 对象的三种初始化方法

  • 构造函数
  • 实例变量初始化(Instance variable initializers)
    class CoffeeCup {
     private int innerCoffee = 355; // "= 355" 就是初始化器 initializer
     // no constructor here
       // ...	
     }
    
  • 实例初始化块(instance initialization block or instance initializer)
    class CoffeeCup {
    private int innerCoffee;
    // 实例初始化块
    {
        innerCoffee = 355;
    }
    // no constructor here
    // ...
    }
    

2 init的结构:

在看结果之前,先看个例子:


public class Test {
	public static void main(String[] args)  {
		new X();//XYYX
	}
}

class X extends Y{
	{
		System.out.print("Y");
	}
	X(){
		System.out.print("X");
	}
}
class Y{
	{
		System.out.print("X");
	}
	Y(){
		System.out.print("Y");
	}
}

问?输出结果是什么?

  1. 调用其他构造函数。An invocation of another constructor
  2. 实例初始化,应该还包括实例初始化块。Instance variable initializers
  3. 当前构造函数的代码。The constructor body

回到这个例子,结果是:XYYX

3 this()和super()上不能try……catch

在this()和super()上try……catch是会炸的。如果你都catch了的话,你就可能忽略这个exception,进而返回不正确的对象。

4 遇到new时

继承和初始化顺序,遇到new时:
先分配空间(子类中的实例变量和父类中的实例变量)
初始化默认值
调用当前类的(注意

5 不能这样提前引用。会拒绝编译

class VirtualCafe {
    private int chairsCount = 4 * tablesCount;
    private int tablesCount = 20;
    //...
}

6 提前引用的两种方式

但是有两种方式来进行提前引用。但是得到的值为默认值。
(1) 初始化实例变量时用一个函数,且这个函数用到了在这个实例变量之后定义的变量。

class VirtualCafe {
    private int chairsCount = initChairsCount();//这样chairsCount的值为0
    private int tablesCount = 20;
    private int initChairsCount() {
        return tablesCount * 4;
    }
    //...
}

(2)在父类中的构造函数中调用父类中被重写的方法(前提是这个父类的构造函数是由子类的构造函数调用的),就可以提前引用。如:


public class Test {
	public static void main(String[] args)  {
		new Coffee(1, 2.5f, true, true);
	}
}

//In source packet in file init/ex16/Liquid.java
class Liquid {
	private int mlVolume;
	private float temperature; // in Celsius
	public Liquid(int mlVolume, float temperature) {
		this.mlVolume = mlVolume;
		this.temperature = temperature;
		method();//如果是从子类调用这个方法,这里的method使用的是子类的方法
	}
	public void method() {
		System.out.println("我在父类");
	}
}

class Coffee extends Liquid {
	private boolean swirling;
	private boolean clockwise;
	public Coffee(int mlVolume, float temperature, boolean swirling, boolean clockwise)  {
		super(mlVolume, temperature);
		this.swirling = swirling;
		if (swirling) {
			this.clockwise = clockwise;
		} 
		System.out.println("success");
	}
	//父类的method被重写了
	public void method() {
		System.out.println(swirling);
	}
}

输入结果:
在这里插入图片描述
而不是:
我在父类
success

7 参考文献

https://www.javaworld.com/article/2076614/core-java/object-initialization-in-java.html?page=2

你可能感兴趣的:(个人思考)