先看代码
class Base {
void test() {
System.out.println("Base");
System.out.println(this);
}
}
public class T extends Base {
void test() {
System.out.println("T");
System.out.println(this);
}
void test2() {
System.out.println("T2");
}
public static void main(String[] args) {
Base b = new T(); // #1
b.test(); // #2
b.test2(); // #3 编译错误
}
}
重点在#1
Base b = new T();
我们用父类声明,但初始化了一个子类。
在#2,调用了test方法,此时虽然b是子类,可以其真实的身份是子类T,所以在运行期间调用的是T的test方法,
在#2, 调用test2方法,虽然在T里面有这个方法,b也是一个T的实例,但在编译期间,编译器以Base作为标准进行衡量,则Base里没有test2这个方法,所以编译失败。
如上就是简单的编译期和运行期的区别。编译期,以声明的引用为基础进行能调用的方法和属性的判断,而运行期,以对象的真实身份进行运行使用。