java 基础
访问修饰符
| 修饰符 | 同一个类 | 同一个包 | 子类 | 整体 |
|---|---|---|---|---|
private |
√ | |||
default |
√ | √ | ||
protected |
√ | √ | √ | |
public |
√ | √ | √ | √ |
方法重写
- 重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值类型。
- 重写方法不能使用比被重写方法更严格的访问权限。
- 重写方法不能抛出比被重写方法范围更大的异常类型。
super
super可用于访问父类中定义的属性super可用于调用父类中定义的成员方法super可用于在子类构造方法中调用父类的构造方法super的追溯不仅限于直接父类
调用父类构造方法
- 在子类的构造方法中可使用
super(参数列表)语句调用父类的构造方法 - 如果子类的构造方法中没有显示地调用父类构造方法,也没有使用
this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法 - 如果子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错
子类对象的实例化过程

多态性
多态 — 在Java中,子类的对象可以替代父类的对象使用
- 一个变量只能有一种确定的数据类型
- 一个引用类型变量可能指向(引用)多种不同类型的对象
1
2
3Person p = new Student();
Object o = new Person(); // Object类型的变量o,指向Person类型的对象
o = new Student(); // Object类型的变量o,指向Student类型的对象
父类类型的变量可以指向子类的对象
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
1 | Student m = new Student(); |
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。
虚拟方法调用
- 正常的方法调用
1
2
3
4Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo(); - 虚拟方法调用(多态情况下)
1
2Person e = new Student();
e.getInfo(); // 调用 Student 类的 getInfo() 方法编译时类型和运行时类型
  编译时 e 为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的 getInfo() 方法。—— 动态绑定
对象类型转换
基本数据类型的类型转换
- 小的数据类型可以自动转换成大的数据类型
- 可以把大的数据类型强制转换成小的数据类型
对Java对象的强制类型转换称为造型
- 从子类到父类的类型转换可以自动进行
- 从父类到子类的类型转换必须通过造型(强制类型转换)实现
- 无继承关系的引用类型间的转换是非法的
- 在造型前可以使用
instanceof操作符测试一个对象的类型
== 操作符与 equals 方法
== 操作符
- 引用类型比较引用(是否指向同一个对象)
1 | Person p1 = new Person(); |
- 基本类型比较值
1 | int a = 5; |
用”==”进行比较时,符号两边的数据类型必须一致(可自动转换的基本数据类型除外),否则编译出错
equals()方法是Object类的方法,由于所有类都继承Object类,也就继承了equals()方法。只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象。格式:obj1.equals(obj2)
特例:当用equals()方法进行比较时,对类File、String、Date及封装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象;
原因:在这些类中覆盖了equals()方法。
多线程
合理利用线程池能够带来三个好处
- 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
杂记
将指定 class 文件打包成 jar
1 | jar cvf jobserver.jar com\bonc\usdp\jobserver\job\IJobServerDataflowJob.class \ |
使用 java 命令运行代码
1 | java -jar <jar-file-name>.jar |
抽象类和抽象接口之间的区别
那么抽象类和抽象接口之间的区别是什么呢?它们不都能包含抽象方法和包含方法体的实现吗?
首先,一个类只能继承一个抽象类,但是一个类可以实现多个接口。
其次,一个抽象类可以通过实例变量(字段)保存一个通用状态,而接口是不能有实例变量的。
菱形继承问题
如果一个类使用相同的函数签名从多个地方(比如另一个类或接口)继承了方法,通过三条规则可以进行判断。
(1) 类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
(2) 如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体。
(3) 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。
取模和与操作
1 | h % n == h & (n - 1) |
相较于取模运算, 与运算效率更高。
JDK 8 中 HashMap 就是计算 index 时就是这么计算的。