不包含子类时
新建一个包含代码块和静态代码块的Animal类,代码如下:
public class Animal {
private String name;
private int legs;
static{
System.out.println("静态代码块");
}
{
System.out.println("代码块");
}
public Animal(String name,int legs) {
this.name=name;
this.legs=legs;
System.out.println("构造函数");
}
}
运行结果如下:
然后把构造方法和代码块的位置改变一下,代码如下:
public class Animal {
private String name;
private int legs;
public Animal(String name,int legs) {
this.name=name;
this.legs=legs;
System.out.println("构造函数");
}
{
System.out.println("代码块");
}
static{
System.out.println("静态代码块");
}
}
运行结果如下:
通过改变代码块、静态代码块和构造方法的位置进行的几次测试可以得出结论:静态代码块先执行,然后是代码块,最后是构造方法。
测试类拥有子类时
新建一个包含代码块和静态代码块的Animal类,代码如下:
public class Animal {
private String name;
private int legs;
public Animal(String name,int legs) {
this.name=name;
this.legs=legs;
System.out.println("父类构造函数");
}
{
System.out.println("父类代码块");
}
static{
System.out.println("父类静态代码块");
}
}
然后新建一个包含代码块和静态代码块的Dog类,为Animal的子类,代码如下:
public class Dog extends Animal {
private String name;
private int legs;
//private static Dog d=new Dog("大黄",5);
{
System.out.println("子类代码块");
}
static{
System.out.println("子类静态代码块");
}
public Dog(String name,int legs) {
super(name,legs);
System.out.println("子类构造函数");
}
}
运行结果如下:
从运行结果可以得出结论:类中如果有静态代码块,则先加载静态代码块,然后是代码块,最后是构造方法;如果该类拥有子类,则父类的静态代码块比子类的静态代码块先加载,子类的静态代码块优先于除父类静态代码块之外的其他父类方法,其余方法都是父类优先于子类执行。
在子类Dog下添加一条代码,其余不变,代码如下:
public class Dog extends Animal {
private String name;
private int legs;
//新添加代码
private static Dog d=new Dog("大黄",5);
{
System.out.println("子类代码块");
}
static{
System.out.println("子类静态代码块");
}
public Dog(String name,int legs) {
super(name,legs);
System.out.println("子类构造函数");
}
}
代码运行结果如下:
可得出结论:静态代码块只执行一次;如果类中有静态变量,则先加载静态变量。在进主方法时,一个类中静态的代码会按照代码的顺序来执行。
总结
1. 被static关键字所修饰的属性和方法,被整个程序共享,可通过类名直接调用。
2. 静态方法中不能访问非静态变量和方法。
3. 在非静态方法中不能声明静态的局部变量。
4. 被static修饰的属性优先被加载,并且优先于主方法。
5. 静态代码块只执行一次,优先于代码块和构造方法。
6. 静态代码块和静态变量同时存在时,按照先后顺序执行。
7. 静态代码块优先于代码块执行,代码块优先于类的构造方法执行。
8. 父类的静态代码块优先于子类的静态代码块执行,子类的静态代码块优先于除父类静态代码块之外的其他父类方法,其余方法都是父类优先于子类执行。