关于静态块,静态变量,构造块,静态方法的加载

昨天笔阿里,就败在了这个java的这个题目上,今晚好好摸索+搜索了一番。

参考笔试题的讨论:

http://bbs.csdn.net/topics/390597457?page=1#post-395635028

 

 

现结论如下:

 

一、什么叫java代码块?

这个问题真是。。。知道不是事,忘了真要命。

分四种:

1)直接在一个方法中出现的{}就称为普通代码块

2)直接在类中定义的没有加static关键字的代码块{}称为构造代码块
在new对象时,构造代码块优先构造方法执行
 
3)用static关键字声明的代码块称为静态代码块,静态块的主要目的是用来为静态属性初始化
 
 4)同步代码块主要出现在多线程中
 
 
java初始化时,编译顺序是怎么样的?
 
 
 
二、java类的生存周期?java代码在进入main函数前都做了什么?
 

类的生命周期分为装载、连接、初始化、使用和卸载的五个过程。

类装载步骤
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,

其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,

各个步骤的主要工作如下:

 

装载:查找和导入类或接口的二进制数据;

链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;
校验:检查导入类或接口的二进制数据的正确性;
准备:给类的静态变量分配并初始化存储空间;
解析:将符号引用转成直接引用;


初始化:激活类的静态变量的初始化Java代码和静态Java代码块。
初始化类中属性是静态代码块的常用用途,但只能使用一次。

卸载:把一些没有出现以下情况会卸载类:

该类所有的实例都已经被回收,即java堆中不存在该类的任何实例。

加载该类的ClassLoader已经被回收。

该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法
 
 
 
这里的讨论也很有启发:

初始化一个类(main方法执行之前),主要是对静态成员变量的初始化,过程分为两步:1)按照静态成员变量的定义顺序在类内部声明成员变量;2)按类中成员变量的初始化顺序初始化。

        本例中,先声明成员变量k,t1,t2,i,n,此时,k=i=n=0;t1=t2=null,然后按顺序初始化这几个成员变量,k复制0,t1初始化,执行构造函数,构造函数执行需要先对对象的成员属性先进行初始化,因此执行 j 的初始化,再执行对象的代码块,再是构造函数本身,同理t2初始化,接下来再是 i 和  n 的初始化,然后到main方法中的对象 t 的初始化,对象的初始化同理t1的初始化。

 参考:http://blog.csdn.net/hyl713/article/details/11925071
 
 
 三、初始化的顺序是怎样的。
 
 

有父类的情况
1. 加载父类
1.1 为静态属性分配存储空间并赋初始值
1.2 执行静态初始化块和静态初始化语句(从上至下)
2. 加载子类(也就是它自己)
2.1 为静态属性分配存储空间
2.2 执行静态初始化块和静态初始化语句(从上至下)
3. 加载父类构造器
3.1 为实例属性分配存数空间并赋初始值
3.2 执行实例初始化块和实例初始化语句
3.3 执行构造器内容
4. 加载子类构造器
4.1 为实例属性分配存数空间并赋初始值
4.2 执行实例初始化块和实例初始化语句
4.3 执行构造器内容
5 回到main()
内部类的加载过程也一样

测试代码: 
 

public class Test6 {
public static void main(String[] args){
new B();
new A.C();
}
}

class A{
private P p1 = new P("A--p1");
static P p3 = new P("A--p3");
public A(){
System.out.println("A()");
}
private P p2 =new P("A--p2");
static{
new P("A--static");
}
{new P("A{...}");}

public static class C {
private P p1 = new P("C--p1");
static P p3 = new P("C--p3");
public C(){
System.out.println("C()");
}
private P p2 =new P("C--p2");
static{
new P("C--static");
}
{new P("C{...}");}
}
}

class B extends A {
int bb=4;
{
System.out.println("bb = "+bb);
}

private P p1 = new P("B --p1");
static P p3 = new P("B -- p3");
public B() {
System.out.println("B()");
}
public P p2 = new P("B -- p2");
static {
new P("B -- static");
}

{new P("B{...}");}
}

class P {
public P(String s) {
System.out.println(s);
}
}

 
四、静态变量没有初始化时,不能被其他的静态变量引用,但可被静态方法引用。
 
前向引用和 非法前向引用  http://bbs.csdn.net/topics/380223885
 
java调试中快捷键:
f5 :运行到下一步,进入函数
f6:运行到下一步,不进入函数
f8 :运行到下一个端点
参考:
posted @ 2013-09-24 23:49  扬大猫  阅读(360)  评论(0)    收藏  举报