第一个:this super构造函数:
今天一同事问我,他写的一段代码为什么编译报错,代码大体构造如下:
package testRun;
public class TestSuper {
public static void main(String[] args) {
System.out.println(new Programmer("小米", 50, "java"));
}
}
class Person {
String name;
int age;
// Person(){}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "Name: " + name + "\nAge: " + age;
}
}
class Programmer extends Person {
String language;
Programmer(String name, int age, String language) {
// super(name, age);
this.name = name;
this.age = age;
this.language = language;
}
public String toString() {
return super.toString() + "\nLanguage: " + language;
}
}
编译会报错愿意如下:
当一个没有构造函数时,系统会默认该类有一个没有参数的构造函数;如果一个类写了构造函数,那么系统就不会给该类在添加默认的构造函数。
当一个子类调用自己的构造函数是,在它的构造韩式开始会默认调用父类的构造函数;如果没有用super(参数…)进行明显的调用父类的构造函数,那么它会默认调用super()父类默认的构造函数(所以如果父类如果重写了带参数的构造函数,那么系统就不会默认给父类添加无参构造器,而子类中没有显式调用父类有参构造器,就会默认调用super()无参构造器,父类中没有该方法,所以会报错。所以,要么在子类中显式调用父类构造函数,要么在父类中再添加一个无参构造器)。
第二:加载基调用顺序:
package test;
class Tree {
static {
System.out.println("静态块。"); // 1
staticColor = "Red";
}
public static String staticColor = getStaticColor();
public String instanceColor = getInstanceColor();
{
System.out.println("实例块。"); // 2
instanceColor = "Brown";
}
public Tree() {
System.out.println("构造方法"); // 3
}
public static String getStaticColor() {
System.out.println("静态方法。"); // 4
return "Green";
}
public String getInstanceColor() {
System.out.println("实例方法。"); // 5
return "Yellow";
}
}
//public class JavaQuestion20160530 {
// public static void main(String[] args) {
// System.out.println(Tree.staticColor); // 6
// Tree tree = new Tree();
// System.out.println(tree.instanceColor); // 7
// }
//}
上面一个类运行时输出的结果是什么那?运行以后你就会发现。
原理大致如下,可能有不对的地方,请指正:
调用普通方法:先父类静态代码块,然后子类静态代码块,然后父类普通代码块,父类构造方法,子类代码块,子类构造方法,最后子类对象调用的方法。
调用静态方法:父类静态代码块,子类静态代码块,子类的静态方法。
如果父类静态代码块和子类静态代码块都只调用一次,如果先调用子类普通方法的时候执行父类和子类的静态代码块,那么后面无论调用子类普通方法还是调用子类静态方法,父类和子类代码块都不再执行。