当变量编译时类型和运行时类型不同时,通过该变量访问它引用对象的实例变量时,实例变量的值由声明时的类型决定;但通过该变量调用它引用对象的方法时,由实际引用对象决定。
调用被子类重写的方法:子类构造函数初始化,会隐式调用父类的无参构造函数,当子类重写了父类的方法并在父类的初始化中被调用的时候,因为方法由实际引用对象决定,也就是子类对象,会导致访问不到子类的变量的值。
java对象是由构造器创建的吗?
构造器只是负责java实例变量执行初始化,执行构造器代码之前,该对象内存已经被分配下来。默认情况:基本类型是0和false,引用类型是null。
继承成员变量和成员方法的区别
方法的行为总是表现出实际类型的行为;实例变量的值总是表现出声明该变量所用类型的行为。
系统内存的子类对象保存着父类的实例变量。
类变量和实例变量
类变量在类初始化阶段完成初始化,实例变量在对象初始化阶段完成初始化。
final修饰符
(1)final修饰变量:被修饰的变量赋值后不能重新赋值
(2)final修饰方法:被修饰的方法不能被重写
(3)final修饰类:被修饰的类不能被继承
final会在编译时进行“宏替换”,javap读取class文件可以发现,final被替换为常量。
@Override 被注释的方法必须重写父类方法,会进行编译检查。
局部内部类(包括匿名内部类)中访问局部变量,该局部变量要用final修饰。
隐式闭包:匿名内部类会扩大局部变量的作用域,产生隐式闭包,所以java语言规定要用final修饰局部变量,防止变量的任意修改造成混乱。