getDeclaredFields()与getFields()
- getDeclaredFields(): 获取所有本类自己声明的属性, 不能获取父类和实现的接口中的属性
- getFields(): 只能获取所有 public 声明的属性, 包括获取父类和实现的接口中的属性
下面两段代码的区别是?
short s1 = 1; s1 = s1 + 1;
short s1 = 1; s1 += 1;
第一段编译报错,s1 + 1自动升级为 int 型,int 型赋值给 s1,需要手动强转
第二段隐含类型强转,不会报错
为什么不能根据返回类型来区分方法重载?
同时方法的重载只是要求两同三不同
- 在同一个类中
- 相同的方法名称
- 参数列表中的参数类型、个数、顺序不同
- 跟权限修饰符和返回值类型无关
如果可以根据返回值类型来区分方法重载,那在仅仅调用方法不获取返回值的使用场景,JVM 就不知道调用的是哪个返回值的方法了。
执行顺序(涉及到继承)
- 对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是
(静态变量、静态初始化块)>(变量、初始化块)>构造器。
- 当涉及到继承时,按照如下顺序执行:
- 执行父类的静态代码块,并初始化父类静态成员变量
- 执行子类的静态代码块,并初始化子类静态成员变量
- 执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量
- 执行子类的构造代码块, 执行子类的构造函数,并初始化子类普通成员变量
& 和 &&
- &:逻辑与,& 两边的表达式都会进行运算
- &&:短路与,&& 左边的表达式结果为 false 时,&& 右边的表达式不参与计算
- | 与 || 同理
可变参数
- 语法:参数类型…
- 每个方法最多只有一个可变参数
- 可变参数必须是方法的最后一个参数
- 可变参数可以设置为任意类型:引用类型,基本类型
- 可变参数也可以传入数组
- 无法仅通过改变 可变参数的类型,来重载方法
- 通过对 class 文件反编译可以发现,可变参数被编译器处理成了数组
向上转型和向下转型
Father f1 = new Son(); // 这就叫 upcasting (向上转型)
// 现在 f1 引用指向一个Son对象
Son s1 = (Son)f1; // 这就叫 downcasting (向下转型)
// 现在f1 还是指向 Son对象
Father f2 = new Father();
Son s2 = (Son)f2; // 出错,子类引用不能指向父类对象
- 把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转换
- 把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转换
包装类
- 基本数据类型方便、简单、高效,但不符合面向对象思维、泛型不支持、集合元素不支持
- 包装类 —> 基本数据类型:包装类对象.xxxValue()
- 基本数据类型 —> 包装类:new 包装类(基本类型值)
- 包装类型比基本类型多了一个非功能值:null
内存泄漏和内存溢出
- 内存溢出(out of memory):指程序在申请内存时,没有足够的内存空间供其使用,出现 out of memory。
- 内存泄露(memory leak):指程序在申请内存后,无法释放已申请的内存空间,内存泄露堆积会导致内存被占光。
- memory leak 最终会导致 out of memory。