Java拾遗(一):浅析Java子类和父类的实例化顺序 及 陷阱
本文主要介绍Java里经常使用的子类和父类的变量实例化顺序及陷阱,并结合一个Android实例来探讨此问题。日后编程中应尽量避免此陷阱。
首先看以下一段代码:
定义一个虚类Server.java
package org.yanzi.test1;
public abstract class Server {
private static final int DEFAULT_PORT = 900;
public Server() {
// TODO Auto-generated constructor stub
int port = getPort();
System.out.println("port = " + port + " DEFAULT_PORT = " + DEFAULT_PORT);
}
protected abstract int getPort();
}
然后定义一个子类SimpleServer.java
package org.yanzi.test1;
public class SimpleServer extends Server {
private int mPort = 100;
public SimpleServer(int port) {
// TODO Auto-generated constructor stub
this.mPort = port;
}
@Override
protected int getPort() {
// TODO Auto-generated method stub
return mPort;
}
}
測试代码:
package org.yanzi.test1;
public class Test1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Server s = new SimpleServer(600);
}
}
測试结果:
port = 0 DEFAULT_PORT = 900
在測试代码里,传了一个參数600,我们希望getPort得到也是600,但遗憾的是得到的是一个大大的0!!!出现这个问题是因对Java子类和父类实例化顺序存在模糊,以下来看下其正确顺序:
1、new一个SimpleServer,SimpleServer的构造函数接收參数600;
2、初始化父类Server的静态变量,DEFAULT_PORT赋值为900;
3、为了实例化子类,首先实例化其父类Server。子类有參数的构造中默认包含了super方法,即调用父类的无參构造函数。因此就到了int port = getPort();这一句,调用子类的getPort方法。子类的getPort方法返回mPort,此时mPort还没有赋值,因此还是0.这就是得到大大的0的原因!!!
4、父类初始化完成后,開始初始化子类的实例变量,mPort赋值100;
5、运行子类的构造函数,mPort赋值600;
6、子类实例化完成,对象创建完了!
真相大白了,再做一个測试。将SimpleServer里的实例变量mPort搞成静态变量例如以下:
package org.yanzi.test1;
public class SimpleServer extends Server {
private static int mPort = 100;
public SimpleServer(int port) {
// TODO Auto-generated constructor stub
this.mPort = port;
}
@Override
protected int getPort() {
// TODO Auto-generated method stub
return mPort;
}
}
測试结果:
port = 100 DEFAULT_PORT = 900
其运行顺序是:
1.第一个步骤同上,SimpleServer接收构造參数600
2.初始化父类的静态代码块,当然包含静态变量,然后初始化子类的静态变量
3.初始化父类的非静态代码,包含非静态的变量等;
4.运行父类的构造函数;
5.初始化子类的非静态代码
6.运行子类的构造函数。
至此完成,终于的结论就是构造函数越简单越好,不要在构造函数里做太多操作。回过头再来看杂家的前文:Android自己定义UI陷阱:LayoutInflater.from().inflate()一定不能工作在父类或虚类里 假设把initView()放在父类里,则子类LAYOUT_ID在使用时还会是0.因此即便要用也要将此弄成static类型的。
Java拾遗(一):浅析Java子类和父类的实例化顺序 及 陷阱的更多相关文章
- java中子类继承父类程序执行顺序
java中子类继承父类程序执行顺序 FatherTest.java public class FatherTest { private String name; public FatherTest() ...
- java中子类继承父类程序执行顺序问题
Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分,它们的执行顺序相对来说比较简单,用程序也很容易验证.比如新建一个测试父类. public ...
- Java入门-浅析Java学习从入门到精通【转】
一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库 ...
- Java 中变量初始化、子类和父类构造器调用的顺序
先说结论 变量初始化 -> 父类构造器 -> 子类构造器 贴代码 Animcal.java 父类 public class Animal { private static int inde ...
- Java子类继承父类的执行顺序
父类的静态代码块(static) 子类的静态代码块(static) 父类的非静态代码块(父类成员初始化) 父类的构造方法 子类的非静态代码块(子类成员初始化) 子类的构造方法
- [ Java学习基础 ] 浅析Java方法调用
先看一个示例,读者可先自行阅读判断输出结果: public class TestClass { private static void testMethod(){ System.out.printl ...
- JAVA面试题 浅析Java中的static关键字
面试官Q1:请说说static关键字,你在项目中是怎么使用的? static 关键字可以用来修饰:属性.方法.内部类.代码块: static 修饰的资源属于类级别,是全体对象实例共享的资源: 使用 s ...
- java 子类重写父类的方法应注意的问题
若想实现一个合格重写方法,而不是重载,那么必须同时满足下面的要求! A.重写规则之一: 重写方法不能比被重写方法限制有更严格的访问级别.(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法 ...
- java 子类、父类中静态代码块、字段,非静态代码块、字段以及构造函数的初始化顺序和次数
一个类中的数据初始化顺序是面试官非常喜欢出的面试题之一,本文用一个实例来介绍java中子类.父类中静态代码块.字段,非静态代码块.字段以及构造函数的执行顺序和次数. 一.包结构
随机推荐
- spring 普通类获取四大作用域request、applicationContext、session、page
几乎所有web应用容器都提供了四种类似Map的结构:application session request page,Jsp或者Servlet通过向着这四个对象放入数据,从而实现Jsp和Servlet ...
- Codeforces #252 (Div. 2) B. Valera and Fruits
题目倒是不难,可是读起来非常恶心 依据题目的描写叙述不easy找到适合存储的方法 后来我就想不跟着出题人的思路走 我自己开一个数组c 令c[a[i]] = b[i] 则c[i] == [j] 代表第i ...
- 该Tiled地图制作拿到项目~~这是偷懒,为了直接复制后写来
1.现在,.h声明private: cocos2d::CCSprite* ninja; cocos2d::CCTMXTiledMap* tileMap; 然后.cpp中增加tileMap = CCT ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block 使用企业库异常处理应用程序模块的 ...
- ProductHunt,TechCrunch和AppStore的差的值
ProductHunt(产品狩猎)硅谷社区的新产品,起初只存在一个技术性的房子维修.然后进入YC训练营已经收到了几百美元的融资2. 这款产品的形式非常easy.粗产物似乎是一个节目的部位,加上一些评论 ...
- SharePoint Server 2010 删除Web应用
SharePoint Server 2010 删除Web应用 因为之前的测试.在SharePointserver创建于非常多Web应用(我是在本机Win7系统上安装的SharePoin ...
- 【原创】poj ----- 1182 食物链 解题报告
题目地址: http://poj.org/problem?id=1182 题目内容: 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submi ...
- DeviceIoControl 直接从磁盘扇区读文件
好久没写博客了,近期看了下DeviceIoControl 关于磁盘的应用,特记一文,以备久后查阅. 首先介绍下,文件在磁盘的存储结构(详细能够到网上查询NTFS文件系统相关的教程后者数据恢复方面教程 ...
- 程序员之---C语言细节22(函数返回指针注意事项<悬空指针>、查看进程能够分配的内存大小)
主要内容:函数返回指针注意事项<悬空指针>.查看进程能够分配的内存大小 #include <stdio.h> char * favorite_fruit() { static ...
- Android架构分析之LOG模块
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:2.3.7_r1 Linux内核版本:android-goldfish-2.6.29 Andro ...