java类的加载顺序题目_Java 类的加载顺序(题)
引例
public class A extends B {
public int a = 100;
public A() {
super();
System.out.println(a);
a = 200;
}
public static void main(String[] args) {
System.out.println(new A().a);
}
}
class B {
public B() {
System.out.println(((A) this).a);
}
}
例子代码很简单,不多做解释了,直接看输出:
0
100
200
对照这个输出,我们来详细分析一下对象的初始化顺序:
为A类分配内存空间,初始化所有成员变量为默认值,包括primitive类型(int=0,boolean=false,…)和Reference类型。
调用A类构造函数。
调用B类构造函数。
调用Object空构造函数。(java编译器会默认加此构造函数,且object构造函数是个空函数,所以立即返回)
初始化B类成员变量,因为B类没有成员变量,跳过。
执行sysout输出子类A的成员变量小a。// 此时为0
初始化A类成员变量,将A类成员变量小a赋值100。
执行sysout输出当前A类的成员变量小a。// 此时为100
赋值当前A类的成员变量小a为200。
main函数中执行sysout,输出A类实例的成员变量小a。// 此时为200
加粗的那两行描述是重点,结论是成员变量初始化是在父类构造函数调用完后,在此之前,成员变量的值均是默认值。 Dzone作者就是栽在这里,没有仔细分析成员变量初始化在对象初始化中的顺序,造成了程序未按原意执行。
其实这类问题,熟悉原理是一方面,本质上只要不在构造函数中插入过多的业务逻辑,出问题的概率也会低很多。
类加载简单时序图
程序的输出是什么?
public class Base {
private String baseName = "base";
public Base() {
callName();
}
public void callName() {
System.out.println(baseName);
}
static class Sub extends Base {
private String baseName = "sub";
@Override
public void callName() {
System.out.println(baseName);
}
}
public static void main(String[] args) {
Base b = new Sub();
}
}
有了前面的引例,这道题答案就比较简单了
答案: null
public class Demo {
class Super {
int flag = 1;
Super() {
test();
}
void test() {
System.out.println("Super.test() flag=" + flag);
}
}
class Sub extends Super {
// int flag;
Sub(int i) {
flag = i;
System.out.println("Sub.Sub()flag=" + flag);
}
@Override
void test() {
System.out.println("Sub.test()flag=" + flag);
}
}
public static void main(String[] args) {
new Demo().new Sub(5);
}
}
答案:
Sub.test()flag=1
Sub.Sub()flag=5
在我刚做这道题的时候也是有不少疑惑
为什么输出会是 1, 5 不应该是 0, 5
因为覆写了,没有指明 super 调用父类方法,父类的方法怎么都不可能被调用
所以自己打断点查找原因得到一个规律
我将构造函数的执行化为 三个阶段
class Super {
int flag = 1; // ②
Super() { // ①
test(); // ③
}
void test() {
System.out.println("Super.test() flag=" + flag);
}
}
通过这个规律,我将注释写在先前的代码上
public class Demo {
class Super {// ③ 除 Object 无继承,开始执行构造函数
int flag = 1; // ⑤ 加载成员变量完毕
Super() { // ④ 程序运行到这里的时候,开始加载成员变量
test(); // ⑥ 调用子类方法
}
void test() {
System.out.println("Super.test() flag=" + flag);
}
}
class Sub extends Super {// ② Sub 类有父类,继续寻找
Sub(int i) { // ⑧ 开始加载子类的构造函数
flag = i; // ⑨ 重新对父类变量 flag 赋值
System.out.println("Sub.Sub()flag=" + flag); // ⑩ 对父类变量进行输出
}
@Override
void test() {
System.out.println("Sub.test()flag=" + flag); // ⑦ 输出父类的变量 flag
}
}
public static void main(String[] args) {
new Demo().new Sub(5); // ① 开始寻找 Sub 类
}
}
PS: 这些都是简单题,还有静态变量,静态类,内部类,内部静态类,内部静态类静态变量 try catch finally return 各种混合...
java类的加载顺序题目_Java 类的加载顺序(题)相关推荐
- java类的两个基本成分_Java类文件的基本结构
欢迎来到""第二期.我们讨论了抽象计算机JVM.如果你对JVM还很陌生,你可以去看看.本期,我们稍稍窥探一下Java类文件的基本结构. 为旅行而生 Java类文件(.class文件 ...
- java类与对象 编程题目_Java类与对象的课后练习
Java类与对象的课后练习编程题(java2实用教程P111) 这章内容自学完了,在做教材课后其他练习题的时候(只要自己仔细)都没啥问题,但在做最后一道上机编程题的时候问题出现了,在阅读题目的时候自己 ...
- java 执行顺序混乱_java类执行顺序问题
经常遇到的面试题,一个类继承另一个类然后问输出的结果是什么.个人觉得就是考类的输出问题(亲测) 第一:单一的类执行顺序 package Test; public class person { stat ...
- java 类及对象的课后作业_JAVA类和对象课后作业
1.使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询"你已经创建了多少个对象?" 代码: //显示类 //YiMingLai 2 ...
- java类的修饰词有哪些_Java类与对象及访问控制修饰词解析
Java 是个纯面向对象语言,不支持过程式编程,所有操作都是基于对象. 一.类 类是 Java 中的一种引用数据类型,引用数据类型值都存储在堆中.类是构造对象的模板,每个类对象都是类通过 new 语句 ...
- java 图片加水印不失真_java实现图片加水印效果
图片加水印代码,这些代码不常用,但是用到的时候需要注意的地方也挺多的,每次都重写比较麻烦,记下来备忘.代码是图片加水印的一般流程,可根据实际项目需要自行修改. 注:代码在JPG和PNG格式图片下测试通 ...
- java设计狗叫和狗咬_Java类谜题47:啊呀!我的猫变成狗了
面的程序使用了一个Counter类来跟踪每一种家庭宠物叫唤的次数.那么该程序会打印出什么呢? class Counter { private static int count = 0; public ...
- java嵌套类中的方法怎么调用_java类与嵌套嵌套后,怎么使用最外层的类建立对象后使用内部类的方法?...
展开全部 /* package whatever; // don't place package name! */ import java.util.*; import java.lang.*; im ...
- 学习java要学类与对象的使用吗_java 类与对象 的概念理解(可以用我们学习多年的蚂蚁哲学套用)...
面向对象其实是一种思考的思想,是解决问题,架构工程的整体解决方案.二早期编程语言的思想是面向过程. 面向过程注重的是过程,过程所涉及的行为,也就是功能.通过选择循环语句等逻辑将参与者连接起来. 面向对 ...
最新文章
- 120万公里「真」无人商用里程如何炼成?出租车物流车车车无人,香港乌鲁木齐城城自动...
- CString与LPCWSTR、LPSTR、char*、LPWSTR等类型的转换【转】
- 10个快速提升技术水平的方法
- Robot Framework 教程 (3) - Resource及关键字 的使用
- 拼智商,谷歌、苹果、微软、亚马逊的AI助手谁赢了?有些结果没料到
- 图解深度学习的笔记:1.MP模型,感知器,BP下的多层感知器
- Appium原理及使用
- 学习C语言——字母金字塔
- edp协议 netty_使用esp8266 arduino 通过EDP协议 将数据传递到onenet平台
- 使用UE4创建一个简单真实的地球(一)
- 字节输入输出流,字符输入输出流
- xxl-job配置发邮件 spring.mail的QQ邮箱配置
- java使用poi生成Excel文件并合并单元格
- JavaScript中内存溢出和内存泄漏
- Cocos Creator基于热更新的分包方案
- 史上最牛最强的linux学习笔记 7.用户和用户组管理
- 用python画正方形
- SA(需求分析师)笔试题目整理
- php判断用户和管理员,php – 检查用户是否是root用户
- 论国产PLC产业化发展
热门文章
- Android Studio Design界面不显示layout控件的解决方法
- 【实践】端智能在大众点评搜索推荐重排序的应用实践
- 广告深度预估技术在美团到店场景下的突破与畅想
- 【报告分享】2021新青年国货消费研究报告:文化觉醒时代,宝藏国货迎复兴机遇.pdf(附下载链接)...
- 【报告分享】转变与机遇:从京东大数据看2020消费市场与品牌成长.pdf(附下载链接)...
- 电商场景中的精排服务实践
- mysql意外关机_MySQL服务器意外关机-无法启动多实例
- tiktok跨境出海?
- Leetcode每日一题:24.swap-nodes-in-pairs(两两交换链表中的节点)
- 给PhotoShop安装Portraiture插件