访问权限
成员访问权限
- 默认成员访问权限为package,只能被同一package内类访问
- protected可被同一package内类访问,因此protected = package + 跨package子类
- 成员访问权限大小:public > protected > package > private
类访问权限
- 默认类访问权限为package,只能被同一package内类访问和继承
- public类访问权限可被所有package内类访问和继承
注1:成员访问权限 = min(成员访问权限, 类访问权限),因此package类成员的public权限和protected权限本质还是package权限
注2:不管是成员访问权限还是类访问权限,package访问权限只是认知上的理解,访问权限本身并无package关键字,默认缺省就是package访问权限
继承
- 只支持单根继承,不支持多重继承,无显式父类则继承自root类Object
- 只有唯一继承方式,public继承,且public无须显式指明
class加载
- class被引用时(包括实例化对象和引用类static成员),jvm会加载相关class文件
- class加载顺序:父类(数据成员类->当前类)->子类(数据成员类->当前类)
- 数据成员类加载顺序与数据成员类(static和non-static)在类中定义顺序一致
初始化
static数据成员初始化
- static数据成员不属于实例对象成员,static数据成员于class加载时初始化,static数据成员初始化顺序与static数据成员在类中定义顺序一致,且只初始化一次
- static数据成员初始化早于non-static数据成员初始化
non-static数据成员初始化
- non-static数据成员属于实例对象成员,non-static数据成员于实例化对象时初始化
- non-static数据成员初始化顺序:父类(non-static数据成员->构造函数)->子类(non-static数据成员->构造函数)
- non-static数据成员初始化顺序与non-static数据成员在类中定义顺序一致
- non-static数据成员若无显式初始化,则初始化为0
this&super
构造函数
- java构造函数功能单一,不含初始化列表,或初始化列表散落在数据成员定义处,因此数据成员初始化先于构造函数调用
- 在性能和安全性之间,java选择了安全性,java数据成员默认初始化为0(引用类型为null)
- java构造函数无初始化列表,因此java构造函数本质并非初始化行为,因此java构造函数与普通函数无本质区别,构造函数多次调用不会导致重复初始化
- java构造函数非常灵活,构造函数可相互调用,但不可递归调用(直接递归或间接递归),构造函数调用语句只能放在主调构造函数首行,构造函数不可被普通函数调用
- 父类构造函数必须显式调用(子类构造函数调用),且必须放在首行,如果调用父类默认构造函数,可omit,因此除非调用父类默认构造函数,否则子类不可调用本类其他构造函数,否则违背构造函数调用必须放在首行原则
复制构造函数
- java只有heap实例对象,无stack实例对象,且实例对象只能通过引用间接访问,不可直接访问实例对象,因此java无复制构造函数
析构函数
- java通过GC(Garbage Collection)机制管理对象内存,因此java无析构函数
赋值操作符函数
- java不支持操作符重载,因此java无赋值操作符函数
non-static方法
- non-static方法默认runtime bind,因此编译期无法确认non-static方法是否会被调用,为避免runtime crash,non-static方法必须实现
- override方法时,子类访问权限不能比父类访问权限小,即子类访问权限必须大于等于父类访问权限(public > protected > package > private)
注:构造函数编译期bind,必须实现,父类子类构造函数之间访问权限大小无限制
static方法
- static方法既可通过类名(类作用域)引用,也可通过实例对象引用
- static方法名字按照类作用域对象名字查找规则查找,因此编译期bind
- static方法编译期bind,但也必须实现