非静态代码块和实例初始化方法 非静态代码块和构造器和显式赋值之间的执行顺序

非静态代码块和实例初始化方法

类的成员: (1)属性 (2)方法 (3) 构造器

类的第四成员:代码块

作用:为属性初始化

一、非静态代码块

1、语法格式
【修饰符】 class 类名 【extends 父类】{
{
非静态的代码块
}
}

2、执行特点
(1)在创建对象的时候自动执行,每创建一个对象就执行一次
如果有多个非静态的代码块,按照顺序执行
(2)先与构造器执行的
(3)非静态代码块与属性的显示赋值他两谁在上面谁先执行
(4)如果创建了子类的对象,会先执行父类的非静态代码块、父类的属性的显试赋值、父类的构造器

3、实例初始化(…)
(1) .java代码编译为 .class时,会把diamante重新组装,如果类中有n个构造器,就会重新组装为n个实例化初始方法。
无参构造 -> ()
有参构造 -> (形参列表)

(2)实例初始化方法由三个部分组成
(A)属性的显式赋值语句
(B)非静态代码块语句
(C)构造器语句
其中(A)(B)是按照顺序组装的,但是(C)无论放在那里,都在最后

(3)创建子类对象的时候会先调用父类的实例化方法

public class TestNonStaticBlock {
	public static void main(String[] args) {
		Son s1 = new Son();

		
		//构造器是最后执行的所以num的值是3
		System.out.println(s1.getNum());//3
		
	}
}

class Father{
	Father(){
		System.out.println("父类的无参构造");
	}
	{
		System.out.println("父类的非静态的代码块1");
	}
	
	{
		System.out.println("父类的非静态的代码块2");
	}
	
	private int i= getNumberI();//为i属性赋值的
	
	public int getNumberI() {
		System.out.println("getNumberI()");
		return 1;
	}

	public int getI() {
		return i;
	}

	
}

class Son extends Father{
	
	Son(){
		System.out.println("无参构造");
		num = 3;
	}
	{
		System.out.println("非静态的代码块1");
		num = 2;
	}
	
	{
		System.out.println("非静态的代码块2");
	}
	
	private int num= getNumber();//为num属性赋值的
	
	public int getNumber() {
		System.out.println("getNum()");
		return 1;
	}

	public int getNum() {
		return num;
	}
	
	
}



在这里插入图片描述

下面程序运行时的内存顺序
在这里插入图片描述

非静态代码块和构造器和显式赋值之间的执行顺序(题目很重要,有时间得看一下)

练习一
public class TestInit1 {
	public static void main(String[] args) {
		A obj = new A(20);
	}
}
class A{
	private int a = getInt();
	
	{
		a++;
		System.out.println("(1)A非静态代码块");
		System.out.println("(1)a = " + a);
	}
	
	A(int num){
		a = num;
		System.out.println("(2)A有参构造");
		System.out.println("(2)a = " + a);
	}
	
	private int getInt(){
		System.out.println("(3)A->getInt");
		System.out.println("(3)a = " + a);
		return 1;
	}
}

/*
(3)A->getInt
(3)a = 0
(1)A非静态代码块
(1)a = 2
(2)A有参构造
(2)a = 20
 */

在这里插入图片描述

练习二
/*
实例初始化的过程:
	(1)实例初始化:调用/执行 实例初始化的方法<init>(...)
	(2)实例初始化方法的方法体由三个部分组成
	第一 属性显示赋值
	第二 非静态代码块
	第三 构造器
	(3)创建子类对象的时候会先执行父类的实例初始化方法
 */

public class TestInit2 {
	public static void main(String[] args) {
		A obj = new B(20);
	}
}
class A{
	private int a = getInt();
	
	{
		a++;
		System.out.println("(1)非静态代码块");
		System.out.println("(1)a = " + a);
	}
	
	A(int num){
		a = num;
		System.out.println("(2)A:有参构造");
		System.out.println("(2)a = " + a);
	}
	
	public int getInt(){
		System.out.println("(3)A->getInt");
		System.out.println("(3)a = " + a);
		return 1;
	}
}
class B extends A{
	private int b = getIntValue();
	
	{
		b++;
		System.out.println("(1)B:非静态代码块");
		System.out.println("(1)b = " + b);
	}
	
	B(int num){
		super(num);
		b = num;
		System.out.println("(2)B:有参构造");
		System.out.println("(2)b = " + b);
	}
	
	public int getIntValue(){
		System.out.println("(3)B->getIntValue");
		System.out.println("(3)b = " + b);
		return 1;
	}
}

/*
(3)A->getInt
(3)a = 0
(1)非静态代码块
(1)a = 2
(2)A:有参构造
(2)a = 20
(3)B->getIntValue
(3)b = 0
(1)B:非静态代码块
(1)b = 2
(2)B:有参构造
(2)b = 20
 */

在这里插入图片描述

练习三

(里面有关于多态重写的问题,比较复杂好好看看)
如果看了不是很懂的话再去看看练习四的注释

/*
实例初始化的过程:
	(1)实例初始化:调用/执行 实例初始化的方法<init>(...)
	(2)实例初始化方法的方法体由三个部分组成
	第一 属性显示赋值
	第二 非静态代码块
	第三 构造器
	(3)创建子类对象的时候会先执行父类的实例初始化方法
	
	(4) 注意:通常面试题当中注意方法重写的问题
	
父类A的实例初始化的方法<init>(...)
❤❤(1)a = getInt();  --> 等价于a = this.getInt()  这个this表示当前的对象,表示正在创建的对象,现在正在创建的是子类的对象,那么通过子类的对象调用getInt()是执行子类的重写的getInt()
(2){
		a++;
		System.out.println("(1)非静态代码块");
		System.out.println("(1)a = " + a);
	}
(3)构造器
        a = num;
		System.out.println("(2)A:有参构造");
		System.out.println("(2)a = " + a);

子类B的实例初始化的方法<init>(...)
(1)b = getInt();
(2){
		b++;
		System.out.println("(1)B:非静态代码块");
		System.out.println("(1)b = " + b);
	}
(3)构造器
		super(num);
		b = num;
		System.out.println("(2)B:有参构造");
		System.out.println("(2)b = " + b);
 */
public class TestInit3 {
	public static void main(String[] args) {
		A obj = new B(20);
	}
}
class A{
	private int a = getInt();//这个地方有一个陷阱,注意是重写
	
	{
		a++;
		System.out.println("(1)非静态代码块");
		System.out.println("(1)a = " + a);
	}
	
	A(int num){
		a = num;
		System.out.println("(2)A:有参构造");
		System.out.println("(2)a = " + a);
	}
	
	public int getInt(){
		System.out.println("(3)A->getInt");
		System.out.println("(3)a = " + a);
		return 1;
	}
}
class B extends A{
	private int b = getInt();
	
	{
		b++;
		System.out.println("(1)B:非静态代码块");
		System.out.println("(1)b = " + b);
	}
	
	B(int num){
		super(num);
		b = num;
		System.out.println("(2)B:有参构造");
		System.out.println("(2)b = " + b);
	}
	
	public int getInt(){
		System.out.println("(3)B->getInt");
		System.out.println("(3)b = " + b);
		return 1;
	}	
}

/*
 (3)A->getInt
 (3)a = 0
 (1)非静态代码块
 (1)a = 2
 (2)A:有参构造
 (2)a = 20
 */

在这里插入图片描述

练习四
/*
 *Override或者Overwrite  重写  覆盖
 *this在类中,就看的是A类中的getInt(),就近原则,因为这个getInt没有被覆盖掉
 *如果getInt()被重写,被覆盖,即使在A类中,通过子类的对象this,看到的只有子类重写后的getInt()方法 
 * 
 */

public class TestInit4 {
	public static void main(String[] args) {
		A obj = new B(20);
	}
}
class A{
	private int a = getInt();//因为getInt() 方法是private,在子类中不可见不会被重写
	//虽然这个地方也是this.getInt(),但是子类中是私有的,所以根据就近原则调用的父类的getInt()
	{
		a++;
		System.out.println("(1)非静态代码块");
		System.out.println("(1)a = " + a);
	}
	
	A(int num){
		a = num;
		System.out.println("(2)A:有参构造");
		System.out.println("(2)a = " + a);
	}
	
	private int getInt(){
		System.out.println("(3)A->getInt");
		System.out.println("(3)a = " + a);
		return 1;
	}
}
class B extends A{
	private int b = getInt();
	
	{
		b++;
		System.out.println("(1)B:非静态代码块");
		System.out.println("(1)b = " + b);
	}
	
	B(int num){
		super(num);
		b = num;
		System.out.println("(2)B:有参构造");
		System.out.println("(2)b = " + b);
	}
	
	private int getInt(){
		System.out.println("(3)B->getInt");
		System.out.println("(3)b = " + b);
		return 1;
	}	
}

在这里插入图片描述

已标记关键词 清除标记
相关推荐
程序员的必经之路! 【限时优惠】 现在下单,还享四重好礼: 1、教学课件免费下载 2、课程案例代码免费下载 3、专属VIP学员群免费答疑 4、下单还送800元编程大礼包 【超实用课程内容】  根据《2019-2020年中国开发者调查报告》示,超83%的开发者都在使用MySQL数据库。使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能!   套餐中一共包含2门MySQL数据库必学的核心课程(共98课时)   课程1:《MySQL数据库从入门到实战应用》   课程2:《高性能MySQL实战课》   【哪些人适合学习这门课程?】  1)平时只接触了语言基础,并未学习任何数据库知识的人;  2)对MySQL掌握程度薄弱的人,课程可以让你更好发挥MySQL最佳性能; 3)想修炼更好的MySQL内功,工作中遇到高并发场景可以游刃有余; 4)被面试官打破沙锅问到底的问题问到怀疑人生的应聘者。 【课程主要讲哪些内容?】 课程一:《MySQL数据库从入门到实战应用》 主要从基础篇,SQL语言篇、MySQL进阶篇三个角度展开讲解,帮助大家更加高效的管理MySQL数据库。 课程二:《高性能MySQL实战课》主要从高可用篇、MySQL8.0新特性篇,性能优化篇,面试篇四个角度展开讲解,帮助大家发挥MySQL的最佳性能的优化方法,掌握如何处理海量业务数据和高并发请求 【你能收获到什么?】  1.基础再提高,针对MySQL核心知识点学透,用对; 2.能力再提高,日常工作中的代码换新貌,不怕问题; 3.面试再加分,巴不得面试官打破沙锅问到底,竞争力MAX。 【课程如何观看?】  1、登录CSDN学院 APP 在我的课程中进行学习; 2、移动端:CSDN 学院APP(注意不是CSDN APP哦)  本课程为录播课,课程永久有效观看时长 【资料开放】 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化。  下载方:电脑登录课程观看页面,点击右侧课件,可进行课程资料的打包下载。
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页