关于创建一个对象的流程以及代码块和属性位置相关详解编程语言

在听毕向东的面向对象时,其总结了创建对象的过程:

1、加载指定的字节码文件进内存。

2、通过new在堆内存中开辟空间,分配首地址值。

3、对对象属性进行默认初始化。

4、调用与之对应的构造函数,构造函数压栈。

5、构造函数中执行隐式的语句super()访问父类中的构造函数。

6、对属性进行显示初始化。

7、调用类中的构造代码块。

8、执行构造函数中自定义的初始化代码。

9、初始化完毕,将地址赋值给制定的引用。

其中第6、7两个步骤其实有点说道的,毕向东这种情况是正常的情况,也就是在类的一开始就对属性进行声明。

但是也有很特殊的情况例如:

package cn.haiyisoft2; 
 
public class ClassDemo09 { 
 
	/** 
	 * @param args 
	 */ 
	public static void main(String[] args) { 
		// TODO Auto-generated method stub 
		// 构造代码块 
		children c1 =new children(); 
		System.out.println(c1.age); 
		children c2 =new children(5); 
		System.out.println(c2.age); 
	} 
 
} 
 
class children { 
	//int age=8; 
	children() { 
		System.out.println("children()"); 
	} 
 
	children(int age) { 
		System.out.println("children(int age)"); 
		this.age=age; 
	} 
 
	private void cry() { 
		System.out.println("cry!"); 
	} 
 
	{ 
		age=10; 
		cry(); 
	} 
	 int age=8; 
}

package cn.haiyisoft2; 
 
public class ClassDemo08 { 
 
	/** 
	 * @param args 
	 */ 
 
	//static { 
		//System.out.println("a"); 
	//} 
 
	public static void main(String[] args) { 
		// TODO Auto-generated method stub 
		// 静态代码块练习 
		//staticcode02 s02 = new staticcode02(); 
		System.out.println(staticcode02.age); 
	} 
 
	//static { 
		//System.out.println("b"); 
	//} 
 
} 
 
class staticcode02 { 
	 
	static { 
		age=10; 
		//System.out.println("static code"+" "+"age="+age); 
		//《深入理解java虚拟机》(第二版)的225页,定义在静态语句块之后的变量,在静态语句块中可以赋值,不能访问。 
	} 
	static int age=9; 
 
	void show() { 
		System.out.println("show fun"); 
	} 
 
	static void show1() { 
		System.out.println("show1 fun"); 
	} 
} 

是的,就是这样在类中不管是类变量还是实例变量,我都是把变量定义在了静态/构造代码块的后面(这样非常不好,极度不推荐),就像《深入理解java虚拟机》(第二版)的225页,定义在静态语句块之后的变量,在静态语句块中可以赋值,不能访问。其实构造代码块如果遇到了属性在构造代码块之后声明时,也会只能赋值不能访问。

而且初始化时不论是对类还是对象进行初始化,都会按照在类声明中出现的次序,执行属性以及各个初始化块(java核心技术(基础版)第八版125页,参考阅读java语言规范中文第三版 8.3.2.3).

如果让类的构造器依赖于属性声明的顺序,那么显得很奇怪并且会引起错误,所以建议将初始化块放在属性定义之后。


原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/17699.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论