Thinking in Java笔记之类及对象的初始化
最近在看《Thinking in Java》这本书,之前一直对类及对象的初始化过程不太清楚,只是感到很模糊。看了这本书关于对象初始化的部分,终于搞明白了。
废话不多说,先上两个例子,实例摘自 《Thinking in Java》。
Test1:
package com.westward;
/**
* @desc 《Thinking in Java》 Demo Page 115
* */
public class Demo14 { public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Inside main");//先初始化static成员变量和static代码块,然后非static成员变量和代码块,然后构造器,然后static main方法
Cups.c1.f(99);//
} /*static Cups x= new Cups();
static Cups y= new Cups();*///
}
class Cup{
public Cup(int marker) {
System.out.println("Cup("+marker+")");
}
void f(int marker){
System.out.println("f("+marker+")");
}
}
class Cups{
static Cup c1;
static Cup c2;
static{
c1= new Cup(1);
c2= new Cup(2);
}
Cups() {
System.out.println("Cups()");// TODO Auto-generated constructor stub
}
}
//run as:Cup(1) Cup(2) Cups() Cups() Inside main f(99)
//注释掉tag2:Inside main Cup(1) Cup(2) f(99)
我们将Cups类定义为下面这个,其初始化过程是一样的。即先初始化static成员变量,然后才static代码块。
class Cups{
static{
c1= new Cup(1);
c2= new Cup(2);
}
static Cup c1;
static Cup c2;
Cups() {
System.out.println("Cups()");// TODO Auto-generated constructor stub
}
}
Test2:
package com.westward; /**
* @desc 《Thinking in Java》 Demo Page 117
* */
public class Demo15 {
Mug c1;
Mug c2;
{
c1= new Mug(1);
c2= new Mug(2);
System.out.println("c1 & c2 initialized");
}
Demo15(){
System.out.println("Mugs()");
} public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Inside main()");
// Demo15 x= new Demo15();//
} }
class Mug{
Mug(int marker) {
System.out.println("Mug("+marker+")");
}
void f(int marker){
System.out.println("f("+marker+")");
}
}
//Inside main() Mug(1) Mug(2) c1 & c2 initialized Mugs()
//注释掉tag2: Inside main()
总结:从Test1和Test2,可以看出,首先,加载拥有主方法main的Demo14这个类,可以理解为jvm默认调用加载拥有main方法的Demo14这个类Demo14.class,然后初始化Demo14里的static修饰的成员变量,然后执行static修饰的代码块,然后执行main方法。main方法里(此处有三个出口):
a.若定义一个类(比如Cups x),并new初始化这个对象Cups(),那么jvm就会加载Cups.class,然后初始化static成员变量,然后执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。
b.若直接调用类的静态方法或者静态类的静态成语,比如调用Cups.c1.f(99),那么jvm同样会加载Cups.class这个类,并且初始化。顺序为:初始化static成员变量,然后执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。
c.若main方法里既没有new对象,也没有调用类的静态成员或静态方法,没有类会被加载,所以没有类会被初始化,没有对象被初始化。
注意:
1.上面的初始化过程,我们假定静态成员,静态代码块,非静态成员,非静态代码块都存在的情况。若某一项不存在,那么顺序是不会变的,我们只需要从这个顺序列表中将其删除就OK。
2.当我们new同一个类(Cups)的多个对象,或者调用Cups的静态方法或者静态成员多次,Cups.class只加载并且初始化一次。也就是说static成员变量和static静态代码块只初始化一次。非静态的对象的非静态成员变量、非静态代码块、构造器初始化次数则和new的次数相等。
3.当我们new了Cups的一个对象,jvm载入Cups.class,并且初始化static修饰的...后,然后会为非静态成员默认初始化值[基本数据类型(int,byte,short,long为0,float,double为0.0,boolean为false,char为''),引用数据类型会将句柄初始化为null],然后若我们显示初始化此成员变量,就会执行显示初始化,然后执行非静态代码块,然后构造器。
Thinking in Java笔记之类及对象的初始化的更多相关文章
- Java笔记—— 类与对象的几个例子
问题1 按要求编写java应用程序: 编写西游记人物类,属性有:身高,名字和武器.方法有:显示名字,显示武器. 在main方法中创建两个对象.猪八戒和孙悟空,并分别为他们的两个属性名字和武器赋值,最后 ...
- Java自学-类和对象 属性初始化
如何进行Java的属性初始化 步骤 1 : 对象属性初始化 对象属性初始化有3种 声明该属性的时候初始化 构造方法中初始化 初始化块 . public class Hero { public Stri ...
- Java基础——类和对象的初始化过程
本节把类和对象的初始化所涉及到的所有代码块阐述一边. 示例代码: public class Demo { private static String name; private String age; ...
- java笔记之类和对象
现在编程的思想分成了两大阵营,面向过程和面向对象.现在谈谈啥是面向对象. 作为一只单身狗,谈“对象”还是很伤心很伤心的(:′⌒`)...... 先看看百度怎么说? 好吧,百度说的太抽象,我换个简单的说 ...
- java笔记 -- 类与对象
封装: 从形式上看, 封装是将数据和行为组合在一个包中, 并对对象的使用者隐藏了数据的实现方式. 对象中的数据称为实例域, 操纵数据的过程称为方法. 对于每个特定的类实例(对象)都有一组特定的实例域值 ...
- JAVA笔记2-面向对象与内存解析
1.java中的变量先声明.再赋值.再使用.(局部变量必须初始化,成员变量默认初始化) 2.基本类型之外的所有类型都是引用类型.基本类型占一块内存,引用类型占两块(所有new出来的东西装在堆内存,因为 ...
- JAVA笔记4__static关键字/对象数组/foreach/方法的可变参数
/** * static关键字:修饰属性(实质就是全局变量).方法(无需本类的对象即可调用此方法).类. * 1.static方法只能调用static方法 * 2.static方法只能访问static ...
- java笔记--String类对象解析与运用
--如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3877236.html "谢谢-- 1.String中的equals和==的 ...
- java笔记1-面向对象思想
合适的方法放在合适的类之中. 设计中,分解出应该具有哪些对象(面向对象),不要再想步骤了(这是面向过程).设计过程: step1:问题中有哪些类和对象(找名词,之后区分是类还是属性) step2:这些 ...
随机推荐
- Python3基础 setattr 设置对象的属性值,如果属性不存在就创建
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- GNU C 中零长度的数组【转】
原文链接:http://www.cnblogs.com/dolphin0520/p/3752492.html 在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNU C中,存在一个非常奇怪的用 ...
- C#预处理器指令【转】
本文转载自:http://www.cnblogs.com/miffylf/p/4005223.html C#有许多名为预处理器指令的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各 ...
- 加强树状数组luogu3368
暴力树状数组30分,这该怎么办: 知识点回顾 差分数组中 开头结尾改变了值之后 求他的前缀,发现区间内所有数都改变 然后我们做差分树状数组 #include<cstdio> using n ...
- POJ 1260 Pearls (斜率DP)题解
思路: 直接DP也能做,这里用斜率DP. dp[i] = min{ dp[j] + ( sum[i] - sum[j] + 10 )*pr[i]} ; k<j<i => dp[j ...
- 到底二级域名和一级域名哪个更利于SEO
到底二级域名和一级域名哪个更利于SEO呢?本文是从百度官方转载详细的介绍:二级域名和一级域名的区别,请各位认真阅读. 二级域名和子域名的区别可以通过以下3点来解读: 一,二级域名的特点 搜索引擎往往将 ...
- UVa 11991 一道简单题
https://vjudge.net/problem/UVA-11991 题意:给出一个包含n个整数的数组,你需要回答若干询问.每次询问两个整数k和v,输出从左到右第k个v的下标. 思路: 把每个数字 ...
- POJ 3295 Tautology(构造法)
http://poj.org/problem?id=3295 题意: 判断表达式是否为永真式. 思路: 把每种情况都枚举一下. #include<iostream> #include< ...
- BZOJ 4416 【SHOI2013】 阶乘字符串
题目链接:阶乘字符串 又是一道不会做的题……看了题解后我被吓傻了…… 首先我们可以有一个显然的\(O(2^nn)\)的做法.我们先预处理出\(g_{i,j}\)表示字符串中\(i\)号位置开始第一个\ ...
- telnet不是内部或外部命令的解决方案
telnet主要是为了维护使用,windows默认不打开这个功能,所有无法登陆 按照下面截图,可轻松打开telnet功能 点击控制面板 选择程序和功能 点击左上角打开 turn windows fea ...