- 浏览: 110466 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
leon.s.kennedy:
jixuezhiyuan 写道你连需要哪些jar包都不说,你是 ...
JUnit4入门 -
jixuezhiyuan:
你连需要哪些jar包都不说,你是只给自己看的吗?
JUnit4入门 -
coolxuhanbing:
,很有指导意义!
SQL优化总结(34条) -
yaya_wiscom:
不错写的蛮好的
SQL优化总结(34条) -
leon.s.kennedy:
sokoo108 写道hellostory 写道sokoo10 ...
Ibatis的CRUD
最近又在翻《thinking in java》,这本书,怎么说呢,以前学java的时候,老师就没有把它作为教材,但是我偏偏只买了这本书,一直收获很大。好了,言归正传,结合自己的偶然遇到的一个在构造函数中调多态方法引起的思考,讲述一下java的初始化到底是怎样的一个过程。
所谓初始化,当然也就指的是变量。变量可以是内置的变量或者我们创建的类的对象。
有人说,本来初始化本来就是一件很简单的事情,的确,但是java作为一门面向对象语言,由于具有继承、多态,静态、动态绑定等多种特性,所以其初始化的情景可谓是五花八门。现在就一步一步的分析其初始化过程。下面就是几个小原则。优先级依次递减。
1、静态块优先
程序首先会执行静态块的内容,这也就有了不写main方法就跑hello world的小故事,相信说到这里,大家就有了思路。我们都知道静态类型是和类绑定的而不是和具体实例对象绑定。也就是说,引用一个静态变量的方式往往是MyClass.xxx.这个特点决定了其在编译的阶段就已经分配好了固定的空间。
2、父类优先
由于继承的特性,当导出类(子类)的对象被创建的时候,程序将向上追溯到最初的父类,执行其初始化的操作。然后一次向下调用子类的构造函数。按照这个思路,那么每一个实例第一个要初始化的必定是Object类了。
3、成员变量优先
一定要注意,成员变量按照其声明的顺序会被初始化,并且立刻被初始化为二进制的0,这个动作发生在所有事件之前,也就是编译器会立刻将分配给对象的空间初始化。一会的小例子将证明这一点。
最后就是调用类的构造方法了。
下面有一个不错的例子,为了演示成员变量最早被初始化为0了,我们将在父类的构造函数中调用子类的方法(利用了多态)。
- package fruit;
- import vege.Inner;
- public class Fruit {
- //static block
- static {
- System.out.println("In Fruit static");
- }
- private Inner i = new Inner(); //a private member
- public Fruit(){
- System.out.println("Before Fruit Constructor");
- show(); //由于多态的特性,此处子类Apple覆写的方法会被调用
- System.out.println("After Fruit Constructor");
- }
- public void show(){
- System.out.println("show:Fruit.");
- }
- public static void main(String[] args) {
- // TODO code application logic here
- new Apple(3);
- }
- }
现在父类中须要初始化的有
- 静态块
- 一个Inner类私有成员
- 构造函数
现在我们看子类的代码
- package fruit;
- public class Apple extends Fruit{
- //静态块
- static{
- System.out.println("In Apple static");
- }
- private int weight = 1; //初始化为1 注意区别这里和 初始化为0
- public Apple(int para_weight){
- System.out.println("Before Apple Constructer: weight = "+weight);
- weight = para_weight;
- System.out.println("Apple Constructor: weight="+weight);
- }
- @Override
- public void show(){
- System.out.println("show apple: weight =" + weight);
- }
- }
- 静态块
- 私有成员weight
- 构造函数
那么当我们运行的时候会有怎样的结果呢?猜想。。。。。
下面就是执行的结果:
Look! 首先执行父类的静态块,之后是子类的静态块,这两个应该没有什么问题。接下来就是对父类成员变量的初始化了。首先是父类的私有成员Inner对象,打印了一条“ Inner Constructor”。
接下来就是父类的构造函数,可见由于java的多态性,Fruit的构造方法调用了其子类Apple的show方法,并且我们可以清晰的看到,此刻Apple类中weight变量的值是0!说明,类的成员变量无论是否赋值,在各种初始化之前早已被设置为二进制0了。
于是乎我想起了很多关于java的书都在说。。“如果类的私有变量没有赋值,就会被设置为0”。。这句话显然把时间弄混了。。。应该是编译器早已初始化了私有变量,均为0,之后才会执行到赋值语句。
父类的构造函数结束之后,再次回到子类,初始化私有变量(也就是我们常说的赋值语句,因为初始为0的工作早做完了)。所以我们才会看到“Before Apple Constructor weight = 1”,执行完构造函数后,我们就看到了weight终于变成了我们创建对象是传进的3了,呼,初始化结束。
总 结
那么总结一下就是这样的:
- 编译器初始化所有的已分配的空间为二进制0 (这是我们的私有变量都会为0,刚才的例子)
- 执行父类静态代码 执行子类静态代码
- 初始化父类成员变量(我们常说的赋值语句)
- 初始化父类构造函数
- 初始化子类成员变量
- 初始化子类构造函数
原文链接:http://www.cnblogs.com/octobershiner/archive/2012/03/12/2391899.html
发表评论
-
Java程序员面试必备的32个要点
2012-05-04 09:09 617本文总结了Java程序员面试的32个要点。这32个要 ... -
常用的正则表达式
2012-04-29 17:43 542关键字.matches你懂的 size=12 ... -
java中实现栈(数据结构)
2012-05-03 09:08 690定义"栈"类 Stack: 插入方 ... -
import static和import的区别
2012-05-03 09:08 448import static静态导入是JDK1.5中的新特性。一 ... -
jdbc sys用户 登录oracle
2012-05-01 20:10 1025如何在JDBC中使用SYSDBA角色连接ORACLE数据 ... -
java时间与字符串转换
2012-05-03 09:08 1073//date转换字符串 Date date = new ... -
java IO
2012-05-04 09:03 549读写文件: 字节 ... -
java注解(下)
2012-05-04 09:03 679为注解增加基本属性 ... -
java注解(上)
2012-05-01 20:10 790JDK1.5新特性:注解 相当于一种标记,加上注解就等 ... -
JAVA 类中 serialVersionUID 的作用
2012-05-03 09:08 664通常在继承 Serializable 接口的类,Ecli ... -
java的String类
2012-04-26 09:19 573昨天看了一道J2SE选择题,是关于Java参数传递的知识,居然 ... -
override(重写)和overload(重载)的异同
2012-04-26 09:19 602方法的重写(Overriding)和 ... -
java国际化
2012-04-26 09:19 428编写配置文件:app_en_US.properties ... -
Java深度理解——Java字节代码的操纵
2012-04-25 09:21 915导读:Java作为业界应 ... -
每个Java初学者都应该搞懂的六个问题
2012-04-25 09:21 973对于这个系列里的问 ... -
Java开发环境搭建详解
2012-04-25 09:20 622一。jdk安装与配置 下载地址:http://download ... -
Java读取Properties文件的六种方法
2012-04-25 09:15 741使用J2SE API读取Properties文件的六种方 ... -
Java代码优化----基础篇
2012-04-25 09:15 818一、为什么要优化可供程序利用的资源(内存、CPU时间、网 ... -
Object流 序列化
2012-04-24 09:44 662import java.io.*; public cl ... -
Java Thread的概述与总结
2012-04-24 09:42 511线程的概述(Introduction) 线程是一个程序 ...
相关推荐
理解ClassLoader的工作机制以及类变量初始化的顺序对于深入理解Java运行时环境至关重要。这篇博文将探讨这两个主题。 首先,让我们深入了解Java的ClassLoader。ClassLoader是一个抽象类,它是Java中的一个关键组件...
在实际进行工作过程中,类装载器依据相应的流程进行操作,先检索与装载再链接,最后初始化。类装载器可以将class文件字节码显示过程图,有效优化传统类装载器数据显示中的不足。 运行时数据区是Java虚拟机在执行...
在Java Web开发过程中,我们经常会遇到一些看似诡异但实际上有其内在原因的问题。这些问题可能是由于对技术理解不深入、代码编写不当或配置错误所导致的。本文将探讨几个常见的Java Web开发中的难题,并尝试提供解决...
1. 类加载机制:JVM通过类加载器将类文件加载到内存中,这个过程包括加载、验证、准备、解析和初始化五个阶段。Java SE 7对这个机制进行了一些优化,比如引入了并行类加载,提高了启动速度。 2. 字符串常量池:在...
其中,JDK 是 Java 开发的基础环境,而 Tomcat 是一个 Servlet 和 JSP 容器,负责管理 Servlet 和 JSP 的初始化、运行和销毁等。 Servlet 是 Java 服务器端小程序,用来进行 web 开发,接收 HTTP 请求,产生静态的 ...
源码提供了对JVM(Java虚拟机)、类库和API的直接洞察,帮助开发者探究Java的内部工作原理。 在Eclipse这样的集成开发环境中,可以通过导入源码来方便地进行阅读和学习。具体步骤包括: 1. 下载Java JDK 1.8的源码...
1. **理解Java Applet生命周期**:学习如何定义applet的初始化、启动、停止和终止方法,了解它们在applet生命周期中的作用。 2. **编写Java Applet代码**:使用Java语言编写applet,包括绘图、响应用户输入、与...
- 类的生命周期包括加载、验证、准备、初始化和卸载五个阶段。 - 双亲委派模型:类加载器在加载类时,会将任务委托给父类加载器,直到Bootstrap ClassLoader。 3. **内存区域**: - 程序计数器:记录当前线程...
其次,Java理解是指深入探究Java的运行机制,如垃圾回收(Garbage Collection)和内存管理,线程同步机制,以及JVM(Java虚拟机)的工作原理。理解这些概念有助于优化程序性能,避免并发问题,并能更好地调试和诊断...
### Java 8 新特性探究——泛型的目标类型推断 #### 概述 Java 8 引入了一系列的新特性,其中泛型的目标类型推断(Target Type Inference)是一项重要的改进,它使得开发者在编写使用泛型的代码时更加简便高效。在...
7. **数组和操作数组的类**:学习如何声明、初始化和操作数组,以及常用的查找和排序算法(如BubbleSort、SelectionSort等)。 **第二阶段:面向对象编程** 1. **对象的本质**:深入理解面向对象编程的核心概念。 2...
这通常是在组件初始化时完成,比如在一个按钮对象上添加监听器。 3. 重写(覆盖)监听器接口中的事件处理方法。这是实现事件响应逻辑的具体地方。事件处理器中的代码将会在相应的事件发生时执行。这些方法可以在本...
这个数组是 `transient` 的,意味着在序列化过程中不会包含这个数组的数据,而是通过其他方式恢复状态。 ```java private transient Object[] elementData; ``` - **`transient` 关键字**: - `transient` 用于...
根据提供的文档信息,本次实验主要聚焦于理解和验证Java虚拟机(JVM)在执行程序时的一系列过程,包括类的加载、初始化以及实例化等关键步骤。以下是对这些知识点的详细阐述: ### 实验五:JVM执行程序的过程 #### ...
4. **数组**:学习一维、二维数组的声明、初始化和操作,以及数组与方法的交互。 5. **字符串处理**:熟悉String类的特性,包括字符串的创建、比较、操作方法如substring、concat、indexOf等。 6. **异常处理**:...
5. **launcher**: 这可能是Java应用程序启动器的源码,它负责解析命令行参数,初始化JVM,并加载主类来启动应用。 通过研究这些源码,我们可以深入了解Java的内存管理机制(如垃圾收集),线程模型,反射机制,以及...
总的来说,《自己动手写Java虚拟机及class文件解析分析工具》提供了一套实用的学习资源,无论是对JVM原理的探究,还是对Java类文件格式的掌握,都能从中获益。通过阅读PDF文档和使用提供的工具,读者将能够深入到...
理解通信协议传输过程中的序列化和反序列化机制 基于框架的RPC通信技术 WebService/ApacheCXF RMI/Spring RMI Hession 传统RPC技术在大型分布式架构下面临的问题 分布式架构下的RPC解决方案 Zookeeper ...
通过分析这款游戏的源代码,我们可以深入探究Java在游戏开发中的核心技术和实践方法。 首先,Java作为一款跨平台的面向对象编程语言,具有丰富的类库和强大的性能,特别适合开发这样的小游戏。游戏的核心部分可能...