java中构造代码块、方法调用顺序问题
1. 继承的概念
继承在本职上是特殊——一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。
2. 继承中的初始化顺序
从类的结构上而言,其内部可以有如下四种常见形态:属性(包括类属性和实例属性)、方法(包括类方法和实例方法)、构造器和初始化块(包括类的初始化块和实例的初始化块)。对于继承中的初始化顺序,又具体分为类的初始化和对象的初始化。
类初始化:
在jvm装载类的准备阶段,首先为类的所有类属性和类初始化块分配内存空间。并在类首次初始化阶段中为其进行初始化,类属性和类初始化块之间的定义时的顺序决定了其初始化的顺序。若类存在父类,则首先初始化父类的类属性和类初始化块,一直上溯到Object类最先执行。
对象初始化:
在new创建对象时,首先对对象属性和初始化块分配内存,并执行默认初始化。如果存在父类,则先为父类对象属和初始化块先分配内存并执行初始化。然后执行父类构造器中的初始化程序,接着才开始对子类的对象属性和初始化块执行初始化。
调用顺序:父类的类属性和类代码块-->子类的类属性和类代码块-->父类的对象属性和代码块-->父类的构造函数-->子类的对象属性和代码块-->子类的构造函数
3、举例说明
//先静态初始化并且只有一次!!然后构造代码块!!再构造方法!!
//声明一个继承自父类的子类时,先把父类的构造代码块及构造方法初始化然后初始化子类的构造代码块和构造方法 class Parent {
public static String p_StaticField = "父类--静态变量";
public String p_Field = "父类--变量";
// 代码块 // 构造函数 public Parent() {
System.out.println("父类--构造器");
}
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
} // 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
} public class StaticBlock extends Parent {
public static String s_StaticField = "子类--静态变量";
public String s_Field = "子类--变量";
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
} // 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
} public StaticBlock() {
System.out.println("子类--构造器");
} public static void main(String[] args) {
System.out.println("-------------------");
new Parent();
System.out.println("-------------------");
new StaticBlock();
}
}
/**Output
* 父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
-------------------
父类--变量
父类--初始化块
父类--构造器
-------------------
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
*/
注:
1. 在对象初始化阶段,属性和方法均针对子类可以从父类继承过来的属性和方法而言,一般而言,都是针对父类中非private而言的。因为private修饰的为父类所特有的,子类没有继承过来,当new子类时,无须为其分配空间并执行初始化。当然了,父类的构造器子类也是不继承过来的,但构造器另当别论。
2. 类的初始化只执行一次,当对同一个类new多个对象时,类属性和类初始化块只初始化一次。
4、注意构造函数中的多态问题
在父类构造函数内部调用具有多态行为的函数将导致无法预测的结果,因为此时子类对象还没初始化,此时调用子类方法不会得到我们想要的结果。
class Glyph {
void draw() {
System.out.println("Glyph.draw()");
}
Glyph() {
System.out.println("Glyph() before draw()");//
draw();
System.out.println("Glyph() after draw()");//
}
}
class RoundGlyph extends Glyph {
private int radius = 1;//
RoundGlyph(int r) {
radius = r;//
System.out.println("RoundGlyph.RoundGlyph(). radius = " + radius);//
}
void draw() {
System.out.println("RoundGlyph.draw(). radius = " + radius);//
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
/**
Glyph() before draw()
RoundGlyph.draw(). radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(). radius = 5
*/
java中构造代码块、方法调用顺序问题的更多相关文章
- Java中构造代码块的使用
例子1 public class Client { { System.out.println("执行构造代码块1"); } { System.out.println("执 ...
- Java中四大代码块的运行顺序(附code)
验证证的方法是写code.例如以下: public class test { static class A { public static String name = "hello" ...
- Java中四大代码块的执行顺序(附code)
验证证的方法是写code,如下: public class test { static class A { public static String name = "hello"; ...
- 【Java基础】2、Java中普通代码块,构造代码块,静态代码块区别及代码示例
Java中普通代码块,构造代码块,静态代码块区别及代码示例.Java中普通代码块,构造代码块,静态代码块区别及代码示例 执行顺序:静态代码块>静态方法(main方法)>构造代码块>构 ...
- Java 中静态代码块初始化问题测试
Java 中静态代码块初始化问题测试 原创 情况一:变量是 static final 修饰的"编译期常量",如 public static final String a = &qu ...
- Java中普通代码块,构造代码块,静态代码块执行顺序
//执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 1 //普通代码块 ...
- java中静态代码块,构造代码块,以及构造方法的执行顺序
写了许久的代码,却把一些基础的东西都给忘了,今天无聊就顺手写了个,然后测试下,发现跟我记忆中的竟然有些出入,作为一个两年的开发,我感觉自己很失败啊. 父类pojo: public class Pojo ...
- Java中普通代码块,构造代码块,静态代码块区别及代码示例
//执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 1 //普通代码块 ...
- 关于java中普通代码块、构造代码块与静态代码块
1.普通代码块 public static void main(String[] args) { /*普通代码块: *直接定义在在方法或语句中出现”{普通代码的执行语句}“的就称为普通代码块. *普通 ...
随机推荐
- ykit入门
init lint pack server watch 1.创建现有工程的ykit项目 在项目文件夹下 ykit init 2.lint 检查当前项目的代码质量 手动执行代码 可验证代码正误 yk ...
- Zabbix增加邮箱后Server宕处理
zabbix版本:4.1 DB为Mysql 过程: 1,为了增加邮件报警功能,按照网上文章,开始增加发送邮件模块.先停postfix,后安装mailx和sendmail. systemctl lis ...
- shell中脚本与函数的使用策略
脚本:运行的副作用不影响父环境,开辟了fork子进程; 函数:副作用,定义的变量,数据默认直接添加到了调用者的环境,也是它自己的环境;不想副作用影响调用者环境,就必须主动用local修饰; shell ...
- 2017-10-6模拟赛T1 手工(handicraft.*)
题目 题解 题意很明显,就不讲了. 我们发现从一个A边形切出一个B边形有几种情况: 1. 得到一个(A-B+2)边形和一个B边形(直线过两顶点): 2. 得到一个(A-B+3)边形和一个B边形(直线过 ...
- 利用div+css实现九宫格,然后用js实现点击每个格子可以随机更改格子(div)的背景颜色
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- stand up
#version_s#1.7#version_e# #update_s#https://files.cnblogs.com/files/dyh221/update.zip#update_e#
- Holer实现外网访问ARM嵌入式Linux系统
公网访问ARM嵌入式Linux系统 实验室里的ARM嵌入式Linux系统,只能在局域网内访问,怎样从公网也能访问内网ARM嵌入式Linux系统? 本文将介绍使用holer实现的具体步骤. 1. 准备工 ...
- python super超类方法
super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复调用( ...
- HML
1.元素分类: 2.浮动: 在非IE浏览器(如Firefox)下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容 ...
- js 小数取整数
1.丢弃小数部分,保留整数部分 parseInt() 22.127456取成22.13 parseInt(5/2) 2 向上取整,有小数就整数部分加1 Math.ceil(5/2) 3,四舍五入 ...