先从一道面试题开始说起:
public class A {
public A() {
System.out.println("A...");
}
static {
System.out.println("A:static");
}
{
System.out.println("A");
}
public void show() {
System.out.println("A:show");
}
}
public class B extends A{
public B() {
System.out.println("B...");
}
static {
System.out.println("B:static");
}
{
System.out.println("B");
}
public void show() {
System.out.println("B:show");
}
}
public class Test {
public static void main(String[] args) {
B b=new B();
A c=new A();
b.show();
c.show();
}
}
问执行结果是啥,这结果
A:static
B:static
A
A...
B
B...
A
A...
B:show
A:show
是这个,然后也说明了java程序执行顺序是
1.先执行父类的静态方法或者静态代码块然后在执行子类的,
因为静态部分是依赖于类,而不是依赖于对象存在的,所以静态部分的加载优先于对象存在。
2.然后执行父类的构造代码块,也就是{}这个东西,应用场景大概为:
2.1
.初始化实例变量
如果每个构造函数都需要初始化变量,即可通过构造代码块来实现.从而取代在每个构造函数调用初始化实例变量的方法.
- 1
- 2
2.2 初始化实例环境
一个对象必须在适当的场景下才能存在,如果没有适当的场景,则就需要在创建对象的时候创建此场景.
3.然后在执行父类的默认构造方法
4.在执行子类的构造代码块
5.在执行子类的默认构造方法
6.执行类中的自定义方法
目前测试大概就这么个步骤。
不过有个问题,额,不过这个问题估计都知道了,就是在内部类中不能有静态的东西存在,因为
首先要明白一下三点:
- static类型的属性和方法,在类加载的时候就会存在于内存中。
- 要想是用某个类的static属性和方法,那么这个类必须要加载到虚拟机- 中。
- 非静态内部类并不随外部类一起加载,只有在实例化外部类之后才会加载。
现在考虑这个情况:在外部类并没有实例化,内部类还没有加载,这时候如果调用内部类的静态成员或方法,内部类还没有加载,却试图在内存中创建该内部类的静态成员,这明显是矛盾的。所以非静态内部类不能有静态成员变量或静态方法。
额,大概就这么个回事,
写的不好,,欢迎吐槽,,