一、阿里巴巴笔试题:

 public class T  implements Cloneable {
public static int k = 0;
public static T t1 = new T("t1");
public static T t2 = new T("t2");
public static int i = print("i");
public static int n = 99; public int j = print("j"); {
print("构造块");
} static {
print("静态块");
} public T(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
} public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
} public static void main(String[] args) { }
}

二、加载过程分析:

执行main时,先加载所在类,声明静态变量,并初始化静态变量执行静态代码块(按顺序执行)

初始化到t1时,暂停类加载,先实例化,此时k=0,而i,n都未初始化,系统默认值为0
初始化j时,k自增为1,i,n为0,输出“1:j i=0 n=0”,n,i自增为1
执行代码块,输出“2:构造块 i=1 n=1”,n,i自增为2
执行构造函数,输出“3:t1 i=2 n=2”,n,i自增为3

初始化到t2时,暂停类加载,先实例化,此时k=3,i,n都还未初始化,但已自增为3
初始化j时,k自增为4,i,n未初始化为3,输出“4:j i=3 n=3”,n,i自增为4
执行代码块,输出“5:构造块 i=4 n=4”,n,i自增为5
执行构造函数,输出“6:t2 i=5 n=5”,n,i自增为6

初始化i,输出“7:i i=6 n=6”,n,i自增为7,返回自增后的i赋值给i
初始化n,赋值99
执行静态块,输出“8:静态块 i=7 n=99”,i自增为8,n自增为100

完成类加载

三、涉及知识点:
1.类加载过程:
加载某类前先加载其父类
加载某类时,先声明静态成员变量,初始化为默认值,再初始化静态成员变量执行静态代码块
初始化静态成员变量执行静态代码块时,是按顺序执行(初始化静态成员变量的本质就是静态代码块)

2.实例化过程:
对某类实例化前,先对其父类进行实例化
实例化某类时,先声明成员变量,初始化为默认值,再初始化成员变量执行代码块
初始化成员变量执行代码块时,是按顺序执行

3.在某类加载过程中调用了本类实例化过程(如new了本类对象),则会暂停类加载过程先执行实例化过程,执行完毕再回到类加载过程

4.类的主动使用与被动使用:
主动使用例子:
1):最为常用的new一个类的实例对象
2):直接调用类的静态方法。
3):操作该类或接口中声明的非编译期常量静态字段
4):反射调用一个类的方法。
5):初始化一个类的子类的时候,父类也相当于被程序主动调用了
(如果调用子类的静态变量是从父类继承过来并没有复写的,那么也就相当于只用到了父类的东东,和子类无关,
所以这个时候子类不需要进行类初始化)。
6):直接运行一个main函数入口的类。

所有的JVM实现,在首次主动使用某类的时候才会加载该类。

被动使用例子:
7):子类调用父类的静态变量,子类不会被初始化。只有父类被初始化。对于静态字段,只有直接定义这个字段的类才会被初始化.
8):通过数组定义来引用类,不会触发类的初始化,如SubClass[] sca = new SubClass[10];
9):访问类的编译期常量,不会初始化类

5.编译期常量:
写到类常量池中的类型是有限的:String和几个基本类型
String值为null时,也不会写到类常量池中
使用new String("xx")创建字符串时,得到的字符串不是类常量池中的

6.对于通过new产生一个字符串(假设为 ”china” )时,会先去常量池中查找是否已经有了 ”china” 对象,
如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此 ”china” 对象的拷贝对象。

7.类成员变量才会有默认的初始值
byte:0(8位)
short:0(16位)
int:0(32位)
long:0L(64位)
char:\u0000(16位),代表NULL
float:0.0F(32位)
double:0.0(64位)
boolean: flase

8.局部变量声明以后,Java 虚拟机不会自动的为它初始化为默认值。
因此对于局部变量,必须先经过显示的初始化,才能使用它。
如果编译器确认一个局部变量在使用之前可能没有被初始化,编译器将报错。

9.数组和String字符串都不是基本数据类型,它们被当作类来处理,是引用数据类型。
引用数据类型的默认初始值都是null

最新文章

  1. win8/10 特技
  2. c#选择文件文件夹
  3. iOS MJRefresh下拉刷新(上拉加载)使用详解
  4. load and initialize
  5. pylint window下安装与使用
  6. Android项目实战--手机卫士18--读取用户的短信内容以及短信备份
  7. Zookeeper理解
  8. jiayuan
  9. Linux操作数据库基本
  10. MySQL Community Server 5.7安装详细步骤
  11. 使用 VSCode 编写 .NET Core 项目之初体验
  12. Centos 7安装python3(PY3.6)
  13. WebSocket(2)---实现游戏公告功能
  14. JAVA对象和类
  15. Unity3D中自带事件函数的执行顺序
  16. 关于unity3dGUI(uGUI)的一些自适应的收获,在这里跟大家分享一下
  17. HDU 5445 Food Problem(多重背包+二进制优化)
  18. 矩形覆盖(python)
  19. linux的cd命令
  20. 数据结构-队列(3)-使用Java内置队列

热门文章

  1. 项目开发-->身份认证及用户登录模块
  2. shell编程之sleep的运用
  3. Hadoop伪分布模式配置
  4. HTML页面加载和解析流程详细介绍
  5. console中一些不常用的实用方法
  6. Asp.net 自定义控件开发相关的几种嵌入资源解决方案
  7. 重构:CSS也面向对象
  8. vs2010创建并使用DLL
  9. c# 获取mac地址的2种方法
  10. POJ 2135