父子类调用顺序
如有错误,敬请指正一直在逃避这个问题,今天认真的写一篇文章,共同学习下吧。有些东西,终究逃不掉。。。
三个java文件,第一个希望读者认真看其注释吧。 (这里做个补充,因为4个static只会随JVM跑一次,故而我不厌其烦得注释掉代码,也是console中重复代码出现的原因)第二第三个是父子类,一目了然!
TestParentAndChild.java
的格式解释:
- console的输出
/**
* Animal animal11 = new Animal();
* 在这里,父类new了一个自身无参对象,程序先是加载父类静态常量和静态块,之后加载无参构造
* here is output 4 animalStaticString
* animal static
* animal constructor with no param
*/ - 执行的代码语句
System.out.println(“Class clazz = new Class(xx)”);//执行的语句
Class clazz = new Class(xx);//实例化
System.out.println();//待用打格式
public class TestParentAndChild {
public static void main(String[] args) {
/**
* Animal animal11 = new Animal();
* 在这里,父类new了一个自身无参对象,程序先是加载父类静态常量和静态块,之后加载无参构造
* here is output 4 animalStaticString
* animal static
* animal constructor with no param
*/
// System.out.println("Animal animal11 = new Animal();");
// Animal animal11 = new Animal();
// System.out.println();
/**
* Animal animal12 = new Animal('mao ke');
* 在这里,父类new了一个自身含参对象,程序先是加载父类静态常量h和静态块,之后加载含参构造
* here is output 4 animalStaticString
* animal static
* animal constructor with 1 param
*/
// System.out.println("Animal animal12 = new Animal('mao ke');");
// Animal animal12 = new Animal("mao ke");
// System.out.println();
/**
* Animal animal13 = new Dog();
* 在这里,父类new了一个子类无参对象,程序首先加载父类的静态常量和静态块,之后加载子类的静态常量和静态块,再之后加载父类的无参构造,最后加载其自身的无参构造
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with no param
* dog with no param
*/
// System.out.println("Animal animal13 = new Dog();");
// Animal animal13 = new Dog();
// System.out.println();
/**
* Animal animal14 = new Dog('quan ke');
* 四个static同上,由于没有显示的加上super(),jvm默认在首行添加super(),所以程序在进入子类含参构造的第一步便是去找该子类的父类的无参构造,之后执行赋值子类狗为犬科,再之后输出其属性值
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with no param
* dog-super with 1 param
* quan ke
* null
*/
// System.out.println("Animal animal14 = new Dog('quan ke');");
// Animal animal14 = new Dog("quan ke");
// System.out.println(animal14.familyName);
// System.out.println(((Dog) animal14).name);
// System.out.println();
/**
* Animal animal14 = new Dog('hashiqi');
* 四个static同上,由于没有显示的加上super(),jvm默认在首行添加super(),所以程序在进入子类含参构造函数的第一步便是去找该子类的父类的无参构造,之后执行赋值子类狗叫哈士奇,再之后输出其属性值
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with no param
* dog-this with 1 param
* null
* hashiqi
*/
// System.out.println("Animal animal14 = new Dog('hashiqi');");
// Animal animal14 = new Dog("hashiqi");
// System.out.println(animal14.familyName);
// System.out.println(((Dog) animal14).name);
// System.out.println();
/**
* Animal animal15 = new Dog('mao Ke', 'cat');
* 四个static同上,在这里我要说一下super(),
* 子类不论进行有参无参构造,
* 若构造中没有super(),jvm默认添加并首行加载,去父类无参走一波;
* 若构造中首行有super(),jvm按行加载,去父类无参走一波;
* 若构造中首行有super(param),jvm按行加载,这次是去父类含参走一下哦
* 在子类中的super.param = param或者是this.param = param都仅仅是单纯的赋值语句
* 读者可以在Dog中把两个Dog(String param)分别解注,都Debug跑一下
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with 1 param
* dog with 1 param
*/
// System.out.println("Animal animal15 = new Dog('mao Ke', 'cat');");
// Animal animal15 = new Dog("mao Ke", "cat");
// System.out.println();
/**
* Dog dog23 = new Dog();
* 如果上面的都认真看了的话,这一段应该秒懂,四个static,之后父类无参构造,再之后子类无参构造
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with no param
* dog with no param
*/
// System.out.println("Dog dog23 = new Dog();");
// Dog dog23 = new Dog();
// System.out.println();
/**
* Dog dog24 = new Dog('cat');
* 同上static,先是父类无参,之后子类有参
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with no param
* dog-this with 1 param
*/
// System.out.println("Dog dog24 = new Dog('cat');");
// Dog dog24 = new Dog("cat");
// System.out.println();
/**
* Dog dog25 = new Dog('quan Ke', 'gou')
* 同上
* here is output 4 animalStaticString
* animal static
* dog static
* here is output 4 dogStaticString
* animal constructor with 1 param
* dog with 1 param
*/
// System.out.println("Dog dog25 = new Dog('quan Ke', 'gou');");
// Dog dog25 = new Dog("quan Ke", "gou");
// System.out.println();
/**
* fen ge xian
*/
/**
* 儿子的马甲太小,爸爸实在穿不上啊!!!ClassCastException
*
* 这里引申两个异常(运行-不强制处理异常||编译-强制处理异常)
* 运行时异常:是RuntimeException类及其子类异常(如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等)
* 这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
* 这些异常通常的说就是由程序的逻辑错误引起的(细心则可避免)
* 特点:Java编译器不会检查它,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
* 编译异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类异常(如IOException、SQLException等以及用户自定义的Exception异常等)
* 从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
*
* 虽然报错,可是由于该错误是运行时异常,导致jvm还是执行了部分代码
* here is output 4 animalStaticString
* animal static
* animal constructor with no param
*
*
* java.lang.ClassCastException:
* tmp_test.Animal cannot be cast to tmp_test.Dog
*/
// System.out.println("Dog dog21 = (Dog) new Animal();");
// Dog dog21 = (Dog) new Animal();
// System.out.println();
// System.out.println("Dog dog22 = (Dog) new Animal('quanKe');");
// Dog dog22 = (Dog) new Animal("quanKe");
// System.out.println();
}
}
public class Animal {
String kind;
static {
System.out.println("animal static");
}
public Animal() {
System.out.println("animal no param");
}
public Animal(String kind) {
this.kind = kind;
System.out.println("animal with param");
}
}
public class Dog extends Animal {
String name;
static {
System.out.println("dog static");
}
public Dog() {
System.out.println("dog no param");
}
public Dog(String kind) {
super.kind = kind;
System.out.println("dog-super with 1 param");
}
// public Dog(String name) {
// this.name = name;
// System.out.println("dog-this with 1 param");
// }
public Dog(String kind, String name) {
super(kind);
this.name = name;
System.out.println("dog with param");
}
}