Java对象相关元素的初始化过程
1、类的成员变量、构造函数、成员方法的初始化过程
当一个类使用new关键字来创建新的对象的时候,比如Person per = new Person();JVM根据Person()寻找匹配的类,然后找到这个类相匹配的构造方法,这里是无参构造,如果程序中没有给出任何构造方法,则JVM默认会给出一个无参构造。当创建一个对象的时候一定对调用该类的构造方法,构造方法就是为了对对象的数据进行初始化。JVM会对给这个对象分配内存空间,也就是对类的成员变量进行分配内存空间,如果类中在定义成员变量就赋值的话,就按初始值进行运算,如果只是声明没有赋初始值的话,JVM会按照规则自动进行初始化赋值。而成员方法是在对象调用这个方法的时候才会从方法区中加载到栈内存中,用完就立即释放内存空间。
初始化过程:成员变量->构造函数->成员方法。
package com.yyq;
/**
* Created by Administrator on 2015-10-30.
*/
class Person {
int age;
String name;
public Person() {
System.out.println("This is Person()");
System.out.println("Name:" + this.name + "; Age:" + this.age);
}
public void show() {
System.out.println("This is show()");
System.out.println("Name:" + this.name + "; Age:" + this.age);
}
}
public class Exercise01 {
public static void main(String[] args) {
Person per = new Person();
per.show();
per.age = 30;
per.name = "Wendy";
per.show();
}
}
2、类的成员变量、静态代码块、构造代码块、局部代码块、构造方法、成员方法的初始化过程
静态代码块是在类中方法外成员位置出现,用了static修饰;一般用于给类进行初始化。静态代码块在这个类第一次被调用或实例化的时候就会被执行。 静态代码块只会执行一次,一般会用来初始化一些值,并且在所有对象中全局共享。构造代码块在类中方法外成员位置出现;可以把多个构造方法中共同的代码放到一起,每次调用构造都执行,并且在构造方法前执行,对对象进行初始化。局部代码块在方法中出现,局部位置;限定变量的生命周期,及早释放,提高内存利用率。
初始化过程:静态代码块(只执行一次)->构造代码块(每次调用构造方法都执行)->构造方法。执行顺序与代码块所在的具体位置无关。
局部代码块的初始化顺序由具体位置决定。
package com.yyq;
/**
* Created by on 2015-10-30.
*/
class CodeBlockDemo {
//静态代码块
static {
int a = 1000;
System.out.println("静态代码块1:"+a);
}
//构造代码块
{
int x = 100;
System.out.println("构造代码块1:"+x);
}
//构造方法
public CodeBlockDemo(){
System.out.println("Exercise02()");
}
//构造方法
public CodeBlockDemo(int a){
System.out.println("Exercise02(int a):"+a);
}
//构造代码块
{
int y = 200;
System.out.println("构造代码块2:"+y);
}
//静态代码块
static {
int b = 2000;
System.out.println("静态代码块2:"+b);
}
}
public class Exercise02{
public static void main(String[] args) {
//局部代码块
{
int x = 10;
System.out.println("局部代码块1:"+x);
}
//出错:找不到符号
//System.out.println(x);
System.out.println("演示一---------------");
CodeBlockDemo ex1= new CodeBlockDemo();
System.out.println("演示二---------------");
CodeBlockDemo ex2 = new CodeBlockDemo();
System.out.println("演示三---------------");
CodeBlockDemo ex3 = new CodeBlockDemo(1);
{
int y = 20;
System.out.println("局部代码块2:"+y);
}
}
}
这里没有将成员变量和成员方法加入分析,但是我们可以知道,静态代码块在类加载的时候就已经初始化了,而成员变量是要在创建对象的时候才会根据构造方法进行分配内存,初始化赋值,所以如果你在静态代码块中打印成员变量或者成员变量赋值的话就会显示出错,显示要将变量类型改为static,而在构造代码块和构造方法中都能正常使用。
初始化过程:静态代码块(只执行一次)->成员变量(每次创建对象都会初始化赋值)->构造代码块(每次调用构造方法都执行)->构造方法(每次创建对象都会调用相匹配的构造方法)->成员方法(对象调用的时候运行)。
3、有继承关系的父类和子类的成员变量、构造方法、成员方法的初始化过程
在创建子类对象的时候会去调用子类的构造方法,其实子类的构造方法的第一条执行语句是super();即会自动去调用父类的无参构造方法,也就是说会自动去检测子类所继承的父类,并对父类的成员变量进行初始化操作。初始化完父类的成员变量、构造方法后,就初始化子类的成员变量和构造方法。因为子类会继承父类的非私有成员变量和成员方法(这里我把成员变量和成员方法都定义为默认访问权限),所以子类中如果定义了相同的成员变量,在初始化的时候就会被覆盖,而成员方法在调用的时候如果父类有子类没有,就执行父类的方法,如果父类没有子类有就执行子类的方法,如果父类有子类也有的话,那子类的成员方法就是复写了父类的成员方法,那最终执行就是子类的成员方法。
初始化过程:父类的成员变量->父类构造方法->子类成员变量->子类构造方法->父类/子类成员方法。
package com.yyq;
/**
* Created by Administrator on 2015-10-30.
*/
class Father{
int age = 40;
String name = "Father";
int num = 321;
public Father(){
System.out.println("Father()");
System.out.println("Name:"+name+"; Age:"+age+"; Num:"+num);
}
public void show(){
System.out.println("I am Father.");
}
public void play(){
System.out.println("Father play.");
}
};
class Son extends Father{
int age = 15;
String name = "Son";
public Son(){
System.out.println("Son()");
System.out.println("Name:"+name+"; Age:"+age+"; Num:"+num);
}
public void show(){
System.out.println("I am Son.");
}
public void study(){
System.out.println("Son play.");
}
}
public class Exercise03 {
public static void main(String[] args){
Son son = new Son();
son.show();
son.play();
son.study();
}
}
Father()
Name:Father; Age:40; Num:321
Son()
Name:Son; Age:15; Num:321
I am Son.
Father play.
Son play.
4、有继承关系的父类和子类的成员变量、静态代码块、构造代码块、构造方法,成员方法的初始化过程
因为如果有继承关系的子类和父类,在创建子类对象的时候会自动的去调用父类的构造方法,对父类的数据进行初始化。但是如果父类和子类都有静态代码块的话,那会先执行父类的静态代码块,接着执行子类的静态代码块,因为静态代码块不需要创建对象才能执行,所以在加载类的时候首先运行静态代码块,然后接着运行父类的构造代码块和父类的构造方法,最后才是运行子类的构造代码块和子类的构造方法。
初始化过程:父类静态代码块->子类静态代码块->父类构造代码块->父类构造方法->子类构造代码块->子类构造方法
package com.yyq;
/**
* Created by Administrator on 2015-10-30.
*/
class BaseClass{
static
{
System.out.println("静态代码块BaseClass");
}
{
System.out.println("构造代码块BaseClass");
}
public BaseClass() {
System.out.println("构造方法BaseClass");
}
}
class SonClass extends BaseClass {
static {
System.out.println("静态代码块SonClass");
}
{
System.out.println("构造代码块SonClass");
}
public SonClass() {
System.out.println("构造方法SonClass");
}
}
public class Exercise04 {
public static void main(String[] args){
SonClass son1 = new SonClass();
System.out.println("-------------------");
SonClass son2 = new SonClass();
}
}
Java对象相关元素的初始化过程的更多相关文章
- Java类变量和成员变量初始化过程
		
一.类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量. 类的编译决定了类的初始化过程. 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: ...
 - java中类的创建及初始化过程
		
java中类的创建及初始化过程无外乎两种情况,其一为单类的创建及初始化,其二具有继承关系的父子类创建及初始化过程. 首先说简单的,单类的创建及初始化过程.在java中我们都知道绝大部分对象的创 ...
 - Java类的实例化的初始化过程
		
A a = new A(); new 创建对象过程: 1.类加载 代码验证 2.给对象在内存(堆)中分配空间(给属性赋值): 3.属性赋默认值: byte,short.int,long -&g ...
 - java对象的几种创建过程
		
java对象的创建过程 (1)用new 语句创建对象,这是最常用的创建对象方法. 下面用一个简单的存在继承关系的实例的创建,来叙述对象创建过程中的细节 概括如下: 执行顺序:(优先级从高到低.)静态代 ...
 - 【深入理解Java虚拟机】类的初始化过程
		
类的初始化过程 类的加载过程.png 加载 将 Class 文件以二进制的形式加载到内存中 验证 校验 Class 文件是否安全,是否被正确的修改等 准备 为类变量申请内存,设置默认值,(初始化变量的 ...
 - 深入理解Java对象的序列化与反序列化的应用
		
当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再 ...
 - (二)Java对象与内存控制
		
一.java的类变量和实例变量: java中的变量可分成两种:成员变量和局部变量. 1.局部变量包括以下几类: 方法内的局部变量:作用域为方法体. 代码块内的局部变量:作用域为代码块 形参:方法内的形 ...
 - Java对象导论
		
Java对象导论 1.1 抽象过程 万物皆对象. 程序是对象的集合(即:类),他们通过发送消息(调用方法)来告知彼此要做的. 每个对象都有自己的由其他对象所构成的存储(引用其他对象或基本类型,即组合) ...
 - Java对象的序列化和反序列化介绍
		
一.什么序列化和反序列化以及作用: java序列化是指把java对象转换为字节序列的过程,而java反序列化是指把字节序列恢复为java对象的过程 1.序列化: 1)对象序列化的最主要的用处就是在传递 ...
 
随机推荐
- jQuery自己编写插件()
			
引言: 在项目中不同页面经常要用到已经写好的交互,比如弹窗,比如下拉菜单,比如选项卡,比如删除... 此时如果每次都把代码copy一份无疑是一件比较麻烦并且无趣的事情,而且个人认为有些low了,我们可 ...
 - java.imageIo给图片添加水印
			
最近项目在做一个商城项目, 项目上的图片要添加水印①,添加图片水印;②:添加文字水印; 一下提供下个方法,希望大家可以用得着: package com.blogs.image; import java ...
 - winForm 中子窗体关闭但不释放对象,方便下次继续打开
			
方法一: 修改子窗体中自动生成的Dispose方法(在Form.Designer.cs文件中) /// <summary> /// Clean up any resources being ...
 - solaris bind 符号未定义
			
ld: fatal: Symbol referencing errors Recently, I am learning the Unix C and come to know that Socket ...
 - PHP7 新特性 简介
			
整理了一些常用的新特性,欢迎点赞!!! 新增操作符 1.?? $username = $_GET['user'] ?? ''; $username = isset($_GET['user']) ? $ ...
 - mysql实例---sql语句中使用@变量
			
本文介绍下,在mysql语句中使用@变量的一个例子,学习下这个特殊变量的用法,有需要的朋友参考下吧. 要求: 计算用户距上次访问的天数,根据imei号区分不同的用户,如果时间段内只有一次访问则为0. ...
 - Oracle SGA参数调整
			
一. SGA的组成: 自动 SGA 管理后,Oracle 可以自动为我们调整以下内存池的大小: shared pool buffer cache large pool java pool stream ...
 - java环境搭建的问题
			
本人用eclipse开发,首先在java官网中下载最新版本的jdk,jdk的版本一定要与eclipse版本位数相同,否则会提示错误“Java was started but returned exit ...
 - 在centos 6.4下安装opencv 2.3.1
			
系统环境介绍: centos 6.4 1.安装依赖包 yum install cmake gcc gcc-c++ gtk+-devel gimp-devel gimp-devel-tools gimp ...
 - try、catch、finally的使用分析---与 return 相关
			
看了一篇文章,讲解的是关于java中关于try.catch.finally中一些问题 下面看一个例子(例1),来讲解java里面中try.catch.finally的处理流程 1 2 3 4 5 ...