java 对象初始化_Java对象初始化
自动初始化(默认值)
一个类的所有基本数据成员都会得到初始化,运行下面的例子可以查看这些默认值:
classDefault{booleant;charc;byteb;shorts;inti;longl;floatf;doubled;public voidshow() {
System.out.println("基本类型 初始化值\n"+
"boolean" + t +"\n" +
"char" + c +"\n" +
"byte" + b + "\n" +
"short" + s + "\n" +
"int" + i + "\n" +
"long" + l + "\n" +
"float" + f + "\n" +
"double" + d + "\n");
}
}public classInitValue {public static voidmain(String[] args) {
Default d= newDefault();
d.show();
}
}
【运行结果】:
基本类型 初始化值
booleanfalse
char
byte0
short0
int0
long0
float0.0
double0.0
其中,char类型的默认值为空(null)。
对于非基本数据类型而言,对象的句柄也会被初始化:
classPerson {privateString name;//setter
}classDefault {
Person p;public voidshow() {
System.out.println("Person" +p);
}
}public classInitValue {public static voidmain(String[] args) {
Default d= newDefault();
d.show();
}
}
【运行结果】:
Personnull
可见,句柄初始化值为null。这就是说,如果没有为p指定初始化值就调用类似于p.setName的方法,就会出现异常。
规定初始化
如果需要自己为变量赋一个初始值,可以在定义变量的同时赋值。
classDefault{boolean t = true;char c = 'A';byte b = 47;short s = 0xff;int i = 24;long l = 999;float f = 1.2f;double d = 1.732;public voidshow() {
System.out.println("boolean" + t +"\n" +
"char" + c +"\n" +
"byte" + b + "\n" +
"short" + s + "\n" +
"int" + i + "\n" +
"long" + l + "\n" +
"float" + f + "\n" +
"double" + d + "\n");
}
}public classInitValue {public static voidmain(String[] args) {
Default d= newDefault();
d.show();
}
}
甚至可以通过一个方法来进行初始化;
classPerson {int i =set();//...
}
这些方法也可以使用自变量:
classPerson {inti;int j =set(i);//...
}
构建器初始化
构建器进行初始化的优点是可以在运行期决定初始化值。例如:
classPerson {intage;
Person() {
age= 89;
}
}
age首先会初始化为0,然后变成89。对于所有基本类型以及对象的句柄,这种情况都是成立的。
初始化顺序
在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那么变量仍然会在调用任何方法(包括构造函数)之前得到初始化。例如:
classPet {
Pet(intage) {
System.out.println("Pet(" + age + ")");
}
}classPerson {
Pet t1= new Pet(1);
Person() {
System.out.println("---Person()---");
t3= new Pet(33);
}
Pet t2= new Pet(2);voidshow() {
System.out.println("show----running");
}
Pet t3= new Pet(3);
}public classOrderOfInitialization {public static voidmain(String[] args) {
Person p= newPerson();
p.show();
}
}
【运行结果】:
Pet(1)
Pet(2)
Pet(3)
---Person()---
Pet(33)
show----running
上例中,虽然t1、t2、t3的定义遍布于类中,但是初始化的先后顺序是由t1、t2、t3的定义顺序决定的(自己动手调换t1、t2、t3看看结果),且初始化优先于构建器执行,当调用Person的构建器时,t3重新初始化。
静态数据的初始化
如果数据是静态的(static),同样的过程也会执行。若属于基本类型,而且未对其进行初始化,就会自动获得自己的标准基本类型初始值;若它是指向一个对象的句柄,除非创建一个对象同它连接起来,否则得到一个空值(null)。如果在定义时初始化,采取的方式与非静态值是不同的,这是因为static只有一个存储区域。例如:
classBowl {
Bowl(intmarker) {
System.out.println("Bowl(" + marker + ")");
}void f(intmarker) {
System.out.println("f(" + marker + ")");
}
}classTable {static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
b2.f(1);
}void f2(intmarker) {
System.out.println("f2(" + marker + ")");
}static Bowl b2 = new Bowl(2);
}classCupboard {
Bowl b3= new Bowl(3);static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}void f3 (intmarker) {
System.out.println("f3(" + marker + ")");
}static Bowl b5 = new Bowl(5);
}public classStaticInitialization {public static voidmain(String[] args) {
System.out.println("Creating new Cupboard() in main");newCupboard();
System.out.println("Creating new Cupboard() in main");newCupboard();
t2.f2(1);
t3.f3(1);
}static Table t2 = newTable();static Cupboard t3 = newCupboard();
}
【运行结果】:
Bowl(1)
Bowl(2)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)
静态代码块
Java允许将其他static初始化工作划分到类内一个特殊的代码块中,这种代码块的形式为static关键字,后面跟着一个方法主体,称为静态代码块。静态代码块只有在第一次生成那个类的对象或首次访问属于那个类的static成员时执行。例如:
classPerson {
Person(intage) {
System.out.println("Person(" + age + ")");
}void f(intage) {
System.out.println("f(" + age + ")");
}
}classPersons {staticPerson p1;staticPerson p2;static{
p1= new Person(1);
p2= new Person(2);
}
Persons() {
System.out.println("Persons()");
}
}public classExplicitStatic {public static voidmain(String[] args) {
System.out.println("Inside main()");
Persons.p1.f(18);//1
}static Persons x = new Persons();//2
static Persons y = new Persons();//2
}
在标记为1的行内访问static对象p1的时候,或在行1被注释而行2未被注释是,用于Persons的static初始化模块就会运行。若1和2都被注释掉,则用于Persons的静态代码块不会执行。
静态属性和静态代码块执行的先后顺序
classPerson {
Person(intage) {
System.out.println("Person("+age+")");
}
}classPersons {static Person p = new Person(2); //1
static{
p= new Person(3);
}static Person p = new Person(2); //2
}public classCompStaticInit {public static voidmain(String[] args) {
}static Persons x = newPersons();
}
根据注释1保留2,注释2保留1的结果分析可知,静态属性和静态代码块的执行顺序取决于编码的顺序。谁在前面就先执行谁。
非静态属性的初始化
classAnimal {
Animal(intage) {
System.out.println("Animal(" + age + ")");
}void f(intage) {
System.out.println("f(" + age + ")");
}
}public classNotStaticInit {
Animal a1;
Animal a2;
{
a1= new Animal(1);
a2= new Animal(2);
System.out.println("a1 & a2 initialized");
}
NotStaticInit() {
System.out.println("NotStaticInit");
}public static voidmain(String[] args) {
System.out.println("Inside main()");
NotStaticInit x= newNotStaticInit();
}
}
类似于静态代码块,匿名代码块与非静态属性的初始化顺序取决于编码顺序。
继承中的对象初始化过程
classInsect {int i = 1;intj;
Insect() {
prt("i = " + i + ", j = " +j);
j= 2;
}static int x1 = prt("static Insect.x1 initialized");static intprt(String s) {
System.out.println(s);return 3;
}
}public class Beetle extendsInsect {int k = prt("Beeklt.k initialized");
Beetle() {
prt("k = " +k);
prt("j = " +j);
}static int x2 = prt("static Bootle.x2 initialized");static intprt(String s) {
System.out.println(s);return 4;
}public static voidmain(String[] args) {
prt("Beetle constructor");
Beetle b= newBeetle();
}
}
【运行结果】:
static Insect.x1 initialized
static Bootle.x2 initialized
Beetle constructor
i = 1, j = 0
Beeklt.k initialized
k = 4
j = 2
对Beetle运行Java时,发生的第一件事情是装载程序到外面找到那个类。在装载过程中,装载程序发现一个基础类,所以随之将其载入。无论是否生成基础类的对象,这一过程都将执行。如果基础类含有另一个基础类,则另一个基础类随即也会载入,以此类推。接下来就在根基础类中执行static初始化,再在下一个衍生类中执行,以此类推。这是因为衍生类的初始化可能要依赖于对基础类成员的初始化。
当类都装载完毕,就能创建对象。首先,这个对象中的所有基本数据类型都会设置成为他们的默认值,对象句柄设为null。然后执行基础类的构建器。这种情况是自动完成的(衍生类的构造函数中默认调用了super(),也可以通过super指定基类的构建器)。基础类构建器完成后,衍生类实例变量就会按本来的顺序得到初始化,然后执行构建器的剩余的主体部分。
总结对象创建的过程:
静态只在类加载的时候执行且只执行一次;
非静态只有在实例化的时候执行,每次创建对象都执行;
静态在非静态之前执行,基类静态优先于衍生类静态执行;
静态属性和静态代码块的执行属性取决于它们在类中的位置,谁在前先执行谁;
非静态属性和构造块的执行顺序取决于它们在类中的位置,谁在前执行谁。
java 对象初始化_Java对象初始化相关推荐
- java程序初始化_Java程序初始化顺序
今天在课上复习了Java的初始化顺序,一直有点疑惑,搞不明白,所以打算写下来,记录一下. 先说一下Java程序初始化的顺序:父类静态变量>父类静态代码块>子类静态变量>子类静态代码块 ...
- java 中的惰性初始化_java惰性初始化
初始化有效地实现了尽可能的惰性.仅使用.class语法来获得对类的引用不会引发初始化.但是为了产生Class引用,Class.forName() 立即就进行了初始化 如果一个static final值 ...
- java类型的数组初始化_java数组初始化详解
介绍 学习Java的朋友想必对数组并不陌生,它需要使用之前对其进行初始化,这是因为数组是引用类型,声明数组只是声明一个引用类型的变量,并不是数组对象本身,只要让数组变量指向有效的数组对象,程序中就可使 ...
- java 未初始化_Java中初始化问题
一.普通类(无继承)的初始化顺序: java编程思想中,对一个对象的创建过程总结如下,假设有一个名为Dog的类: 1.即使没有显示的使用static关键字,构造器实际上也是静态方法.因此当首次创建一个 ...
- java arraylist静态初始化_Java 中初始化 List 集合的 6 种方式!
1.常规方式 List languages = new ArrayList<>(); languages.add("Java"); languages.add(&quo ...
- java静态实例初始化_Java静态初始化,实例初始化以及构造方法
Java静态初始化,实例初始化以及构造方法 首先有三个概念需要了解: 一.静态初始化:是指执行静态初始化块里面的内容. 二.实例初始化:是指执行实例初始化块里面的内容. 三.构造方法:一个名称跟类的名 ...
- java 对象复活_Java对象复活
java 对象复活 总览 收集覆盖了finalize()的对象之后,将其添加到终结处理队列中,以在调用每个对象的finalize()方法之后进行清理. 如果您复活了物体,会发生什么? 何时定案? fi ...
- java jol原理_Java对象布局(JOL)实现过程解析
java对象布局JOL(java object layout),描述对象在堆内存的布局.如下图: 1.markword 固定长度8byte,描述对象的identityhashcode,分代年龄,锁信息 ...
- java开源对象池_JAVA 对象池
GenericObjectPool利用一个org.apache.commons.collections.CursorableLinkedList对象来保存对象池里的对象.这种对象池的特色是: 可以设定 ...
最新文章
- Introduction to random forests
- 【转载】ABAP自定义长文本的处理
- Qt for Android 调用android原生接口分享图片或文字
- 基于TensorFlow,人声识别如何在端上实现?
- 月息2%的贷款算高利贷吗?
- LeetCode 2019 力扣杯全国秋季编程大赛
- android菜单更改,Android修改分析:删除设置中菜单
- Windows服务程序
- html中出现的script失效
- 迷宫最短路径-货郎担问题的解决思路
- 高速信号传输约翰逊 pdf_?高速滑环生产加工问题的具体分析
- 迅捷PDF虚拟打印机怎么安装和使用
- UE4-蓝图-角色的移动,视角控制(五)人物走动到停下过度动画
- 【PMP】风险应对策略
- 《Solar Energy Materials and Solar Cells》期刊介绍(SCI 2区)
- uni 讯飞文字转语音 详解
- 主成分分析(PCA)与K-L变换
- potplay播放器录制音频
- matlab对三维面求积分,matlab三维数值积分问题
- bzoj2144 [2011集训队出题] 跳跳棋 倍增 lca