重写方法访问权限不能变小,返回类型和抛出的异常类型不能变大,必须加 @Override 。
Q4:类之间有哪些关系? 类关系 描述 权力强侧 举例继承 父子类之间的关系:is-a 父类 小狗继承于动物
实现 接口和实现类之间的关系:can-do 接口 小狗实现了狗叫接口
组合 比聚合更强的关系:contains-a 整体 头是身体的一部分
聚合 暂时组装的关系:has-a 组装方 小狗和绳子是暂时的聚合关系
依赖 一个类用到另一个:depends-a 被依赖方 人养小狗,人依赖于小狗
关联 平等的使用关系:links-a 平等 人使用卡消费,卡可以提取人的信息
Q5:Object 类有哪些方法?
equals:检测对象是否相等,默认使用 == 比较对象引用,可以重写 equals 方法自定义比较规则。equals 方法规范:自反性、对称性、传递性、一致性、对于任何非空引用 x,x.equals(null) 返回 false。
hashCode:散列码是由对象导出的一个整型值,没有规律,每个对象都有默认散列码,值由对象存储地址得出。字符串散列码由内容导出,值可能相同。为了在集合中正确使用,一般需要同时重写 equals 和 hashCode,要求 equals 相同 hashCode 必须相同,hashCode 相同 equals 未必相同,因此 hashCode 是对象相等的必要不充分条件。
toString:打印对象时默认的方法,如果没有重写打印的是表示对象值的一个字符串。
clone:clone 方法声明为 protected,类只能通过该方法克隆它自己的对象,如果希望其他类也能调用该方法必须定义该方法为 public。如果一个对象的类没有实现 Cloneable 接口,该对象调用 clone 方***抛出一个 CloneNotSupport 异常。默认的 clone 方法是浅拷贝,一般重写 clone 方法需要实现 Cloneable 接口并指定访问修饰符为 public。
finalize:确定一个对象死亡至少要经过两次标记,如果对象在可达性分析后发现没有与 GC Roots 连接的引用链会被第一次标记,随后进行一次筛选,条件是对象是否有必要执行 finalize 方法。假如对象没有重写该方法或方法已被虚拟机调用,都视为没有必要执行。如果有必要执行,对象会被放置在 F-Queue 队列,由一条低调度优先级的 Finalizer 线程去执行。虚拟机会触发该方法但不保证会结束,这是为了防止某个对象的 finalize 方法执行缓慢或发生死循环。只要对象在 finalize 方法中重新与引用链上的对象建立关联就会在第二次标记时被移出回收集合。由于运行代价高昂且无法保证调用顺序,在 JDK 9 被标记为过时方法,并不适合释放资源。
getClass:返回包含对象信息的类对象。
wait / notify / notifyAll:阻塞或唤醒持有该对象锁的线程。
Q6:内部类的作用是什么,有哪些分类?内部类可对同一包中其他类隐藏,内部类方法可以访问定义这个内部类的作用域中的数据,包括 private 数据。
内部类是一个编译器现象,与虚拟机无关。编译器会把内部类转换成常规的类文件,用 $ 分隔外部类名与内部类名,其中匿名内部类使用数字编号,虚拟机对此一无所知。
静态内部类: 属于外部类,只加载一次。作用域仅在包内,可通过 外部类名.内部类名 直接访问,类内只能访问外部类所有静态属性和方法。HashMap 的 Node 节点,ReentrantLock 中的 Sync 类,ArrayList 的 SubList 都是静态内部类。内部类中还可以定义内部类,如 ThreadLoacl 静态内部类 ThreadLoaclMap 中定义了内部类 Entry。
成员内部类: 属于外部类的每个对象,随对象一起加载。不可以定义静态成员和方法,可访问外部类的所有内容。
局部内部类: 定义在方法内,不能声明访问修饰符,只能定义实例成员变量和实例方法,作用范围仅在声明类的代码块中。
匿名内部类: 只用一次的没有名字的类,可以简化代码,创建的对象类型相当于 new 的类的子类类型。用于实现事件监听和其他回调。
Q7:访问权限控制符有哪些? 访问权限控制符 本类 包内 包外子类 任何地方public √ √ √ √
protected √ √ √ ×
无 √ √ × ×
private √ × × ×
Q8:接口和抽象类的异同?