今天在CSDN上查询学习static使用方式的时候,引出了一个细节性的问题,这里不多加阐述,只做自我学习结果记忆,具体文章可以查看原作者解释。
引入第一位作者文章——Java中的static关键字解析(http://www.cnblogs.com/dolphin0520/p/3799052.html),对其中一段代码的继承部分稍做改变:
public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
}
public Test() {
System.out.println("test constructor");
}
public static void main(String[] args) {
new MyClass();
}
}
class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
}
class MyClass extends An {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
}
public MyClass() {
System.out.println("myclass constructor");
}
}
class An {
Person person = new Person("An");
static{
System.out.println("an static");
}
public An(){
System.out.println("an constuctor");
}
public void pr(){
System.out.println("******");
}
}
输出结果:
test static
an static
myclass static
person static
person An
an constuctor
person MyClass
myclass constructor
主要是理解和掌握在类加载过程中执行顺序,静态代码块首先在类加载的时候就会执行,而并未加载其它非静态方法(非类成员),只有当需要初始化时候,会执行构造方法,而非普通方法(不论方式是否有static修饰符)。
这里在搜索结果中引出了另一个小细节
第二位作者的文章——【深入理解Java虚拟机】类加载机制 (http://blog.csdn.net/shakespeare001/article/details/51765353),原文现在还看不懂,但其中一段代码输出结果却让我觉得应该注意:
class ConstClass{
static{
System.out.println("ConstClass init!");
}
public static final String HELLOWORLD = "hello world";
}
public class Test {
public static void main(String[] args) {
System.out.println(ConstClass.HELLOWORLD);
}
}
输出结果:
hello world
并未执行静态代码块里的代码。作者原文说明:
常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
知识点:
1、Java初始化,加载顺序:父类静态成员变量,父类静态代码块,子类静态成员变量,子类静态代码块,父类非静态成员变量,父类非静态代码块,父类构造函数,子类非静态成员变量,子类非静态代码块,子类构造函数。
2、不能使用this,super关键字。