一、非静态代码块

  1、声明格式

【修饰符】 class 类名 {
{
非静态代码块
}
}

  2、非静态代码块中的代码执行时机

    (1)在"每次"创建对象的时候执行

    (2)比构造方法早

    Demo:

 class MyClass{
private String str; public MyClass(){
System.out.println("无参构造2");
}
public MyClass(String str){
this.str = str;
System.out.println("有参构造3");
} {
System.out.println("非静态代码块1");
}
}

    运行结果:先执行非静态代码中输出"非静态代码块1",然后执行无参构造方法输出"无参构造2"。

  3、实例初始化过程

    初始化过程:创建对象时,为对象进行初始化的操作

    执行顺序:

① 为成员变量显示赋值

② 执行非静态代码块

③ 执行构造器

    图解:

    Java 编译器其实,会把这三个部分的代码,合成一个叫做 <init>(【形参列表】) 实例初始化方法。

    即编译后的 .class 字节码文件中,是没有构造方法这个概念的。

    <init>(【形参列表】) 实例初始化方法的代码就是由三个部分组成:

① 成员变量显示赋值的代码

② 非静态代码中的代码

③ 构造器中的代码

    注意:

      1、其中的 ① 和 ② 按顺序执行,而 ③ 一定是它们当中的最后执行的。

      2、有几个构造器,就会有几个实例初始化方法。那么当创建对象的时候,调用对应的构造器时,其实执行的是对应的实例初始化方法 <init>(【...】)

二、继承中的非静态代码块

  1、继承案例

    先来看一个没有非静态的代码块的继承关系:

    Demo:

 public class TestInit {
public static void main(String[] args) {
Father f = new Father();
//执行父类的无参构造 Son s = new Son();
//先执行父类的无参构造,再执行子类的无参构造 Son s2 = new Son("HelloWorld");
//先执行父类的无参构造,再执行子类的有参构造1 Son s3 = new Son("Java", 10);
// 先执行父类的无参构造,再执行子类的有参构造1,然后再执行子类的有参构造2 }
}
//父类
class Father{
public Father(){
System.out.println("父类的无参构造");
}
}
// 子类
class Son extends Father{
private String str;
private int num; public Son(){
//隐含了super(); 子类的构造器中一定会调用父类的构造器,默认调用父类的无参构造
System.out.println("子类的无参构造");
} public Son(String str){
//隐含了super()
this.str = str;
System.out.println("子类的有参构造1");
} public Son(String str,int num){
this(str); //这里有this就不会有super了,然后调用本类中的构造方法
this.num = num;
System.out.println("子类的有参构造2");
}
}

  2、含有非静态代码块的继承关系

    (1)先执行父类的实例初始化方法

      它由三部分组成:

① 成员变量的显示赋值

② 非静态代码块

③ 构造方法

    (2)再执行子类的实例初始化方法

      它由三部分组成:

① 成员变量的显示赋值

② 非静态代码块

③ 构造方法

    注意:

    ① super() 或 super(实参列表) 之前说的是调用父类的构造器,其实是调用父类对应的实例初始化方法

    ② super() 或 super(实参列表) 之前说的是在子类构造器的首行,其实是在子类实例初始化方法的首行,所以会先完成父类的初始化,再进行子类的初始化。

    Demo:

 public class TestInit {
public static void main(String[] args) {
Fu f = new Fu(); //
System.out.println("==========");
Zi z = new Zi(); //
}
} class Fu{
private String strFu = assignFu();
{
System.out.println("(1)父类的非静态代码块");
}
public Fu(){
System.out.println("(2)父类的无参构造");
}
public String assignFu(){
System.out.println("(3)父类的assignFu()");
return "fu";
}
}
class Zi extends Fu{
private String strZi = assignZi();
{
System.out.println("(4)子类的非静态代码块");
}
public Zi(){
//super() ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
System.out.println("(5)子类的无参构造");
} public String assignZi(){
System.out.println("(6)子类的assignZi()");
return "zi";
}
}

   运行结果:

     

      图解:

  

  3、含有非静态代码块的重写继承关系

    Demo:

 public class TestInit {
public static void main(String[] args) {
Ba b = new Ba(); //
System.out.println("============");
Er r = new Er(); //612645,因为子类重写了assign() }
}
class Ba{
private String str = assign();
{
System.out.println("(1)父类的非静态代码块");
}
public Ba(){
System.out.println("(2)父类的无参构造");
}
public String assign(){
System.out.println("(3)父类的assign()");
return "ba";
}
}
class Er extends Ba{
private String str = assign();
{
System.out.println("(4)子类的非静态代码块");
}
public Er(){
//super() ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
System.out.println("(5)子类的无参构造");
} public String assign(){
System.out.println("(6)子类的assign()");
return "er";
}
}

  运行结果:

  

  图解:

  注意:this在构造器中,在实例化初始化方法中,代表的是正在创建的对象,当创建子类对象时,因为子类重写的 assign(),那么执行是子类重写的 assign() 方法。

  

Java 面向对象—非静态代码块的更多相关文章

  1. java 子类、父类中静态代码块、字段,非静态代码块、字段以及构造函数的初始化顺序和次数

    一个类中的数据初始化顺序是面试官非常喜欢出的面试题之一,本文用一个实例来介绍java中子类.父类中静态代码块.字段,非静态代码块.字段以及构造函数的执行顺序和次数. 一.包结构

  2. JAVA程序执行顺序(静态代码块》非静态代码块》静态方法》构造函数)

    总结:静态代码块总是最先执行. 非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行. 父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非 ...

  3. java中静态代码块,非静态代码块,构造函数

    关于静态代码块 静态代码块的写法: static { System.out.println("我是静态代码块"); } 静态代码块的特点: 1.执行优先级高于非静态的初始化块,它会 ...

  4. Java静态代码块与非静态代码块

    静态代码块,格式是 static{ },随着类的加载而加载,且只执行一次. 在程序中,执行的优先级最高. 非静态代码块,格式是{ },在创建对象的时候运行(即new一个对象的时候),每创建一次对象就执 ...

  5. Java非静态代码块和静态代码块

    类中存在两种特殊的代码块,即非静态代码块和静态代码块,前者是直接由 { } 括起来的代码,而后者是由 static{ } 括起来的代码. 非静态代码块在类初始化创建实例时,将会被提取到类的构造器中执行 ...

  6. Java中静态变量、静态代码块、非静态代码块以及静态方法的加载顺序

    在研究单例设计模式的时候,用到了静态变量和静态方法的内容,出于兴趣,这里简单了解一下这四个模块在类初始化的时候的加载顺序. 经过研究发现,它们的加载顺序为: 1.非静态代码块 2.静态变量或者静态代码 ...

  7. 浅谈Java中静态代码块和非静态代码块

    静态代码块: static{} 执行优先级高于非静态的初始化块,它会在类初始化(类初始化这个问题改天再详细讨论)的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员. 非静 ...

  8. Java子父类间静态代码块、非静态代码块、构造方法的执行顺序

    子类A继承父类B,A a=new A(); 正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A ...

  9. 静态代码块&非静态代码块&构造函数

    总结:静态代码块总是最先执行.非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行.父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非静态 ...

随机推荐

  1. Shell编程——多命令顺序执行、管道、grep命令

    1.多命令执行符: (1)命令1:命令2    多个命令顺序执行,没有逻辑联系,即使命令1出错,命令2依旧执行. (2)命令1&&命令2:只有命令1正确执行,命令2才能正确执行:命令1 ...

  2. rpm 子包创建学习

    rpm 在打包的时候,可以创建子包,这样可以清晰的进行软件包的拆分,以下是结合官方文档学习 的一个实践 预备条件 需要安装rpmdevtools spec 文件 内容 Name: foo Versio ...

  3. NDCG、AUC介绍

    https://blog.csdn.net/u014313009/article/details/38944687 SIGIR的一篇推荐算法论文中提到用NDCG和AUC作为比较效果的指标,之前没了解过 ...

  4. VS Code 安装与配置(使用MSYS2环境与mingw-w64 编译环境)

     更正了顺序,之前不知道怎么回事,内容顺序乱了 力求完美.详细,所以希望懂的人留言指点一下. 目前已经开始添加原理解释,希望大家能分享一些gcc gdb C语言等方面优秀链接 后续会慢慢增添内容,修正 ...

  5. linux .pid文件简述

    PID全称是Process Identification. PID是进程的代号,每个进程有唯一的PID编号.它是进程运行时系统随机分配的,并不代表专门的进程.在运行时PID是不会改变标识符的,但是你终 ...

  6. nginx 日志之 access_log过滤

    一个网站,会包含很多元素,尤其是有大量的图片.js.css等静态元素.这样的请求其实可以不用记录日志. 配置示例: location ~* ^.+\.(gif|jpg|png|css|js)$ { a ...

  7. 2018-2019-2 网络对抗技术 20165318 Exp 9 Web安全基础

    2018-2019-2 网络对抗技术 20165318 Exp 9 Web安全基础 基础问题回答 实践过程记录 WebGoat安装 SQL注入攻击 1.命令注入(Command Injection) ...

  8. .net core 使用本地包

    环境:.net core 2.2 类库:.Net  Standard 2.0 旧版本:   发布你自己的Nuget包 如果不想把包发布到nuget上面供别人引用,然后你有没有服务器,我们只能使用本地包 ...

  9. TreeMap源码分析2

    package map; import org.junit.Test; import com.mysql.cj.api.x.Collection; import map.TreeMap1.Ascend ...

  10. Isilon的WebUI上指定跨时区时间的小问题

    Isilon的WebUI的界面长这样: 假设我们在中国,也就是GMT+8的时区,我们想修改一个远在美国的Isilon cluster的时间. 你会发现,界面上用于指定时间的地方应该填写的不是下面选择的 ...