面向对象三大特性
封装, 多态, 继承
基本数据类型
一字节 (Byte) 占八位 (bit)
JDK, JRE, JVM
JDK (Java Development Kit) : Java 开发工具包, 包括了 JRE, 编译器 javac, 和调试工具 Jconsole, jstack 等
JRE (Java Runtime Environment) : Java 运行时环境, 包括了 JVM , Java 基础类库. 是使用 Java 语言编写程序运行的所需环境
JVM : Java 虚拟机, 可在其上运行 Java 代码
Java 代码, 运行流程
- 先通过 javac.exe 编译器, 对源文件进行编译, 生成 .class 文件
- 启动 Java 虚拟机, 运行 .class 文件, Java 虚拟机会将 .class 文件转换成平台能够理解的形式来运行
运算符
位运算符 : & | ~ ^
移位运算符:
<<
左移, 低位补 0>>
右移, 高位补符号位>>>
无符号右移, 高位补 0
循环
switch(表达式) {case 常量值: {.....[break;]}case 常量值: {.....[break;]}....default: {.....[break;]}}
do {循环语句;
} while(循环条件);
实参和形参
对于基础数据类型来说, 传值调用, 形参为实参内容的拷贝
对于引用数据类型来说, 传址调用, 传的是对象的地址, 那么形参和实参指向同一片地址, 即可以理解为传的就是对象本身了
基本类型变量 & 引用类型变量
基本变量的变量空间中直接存放的是其对应的值
对象的引用, 其空间中存的是对象所在空间的 (起始) 地址
重载
如果多个方法的名字相同, 参数列表不同, 则称该几种方法被重载了
- 方法名相同
- 参数列表不同 (参数个数, 参数类型, 类型的次序)
- 与返回值类型无关
- 编译器 (javac) 在编译阶段, 会对实参类型进行推演, 根据推演的结果决定调用哪个方法
这里有个方法签名的概念 : 经过编译器编译修改过后, 方法的最终名字
具体方式 : 方法全路径名 + 参数列表 + 返回值类型, 构成方法完整的名字
数组
动态初始化 : 创建数组时直接指定元素个数
T[] 数组名 = new T[N];
静态初始化 : 创建数组时不直接指定元素个数, 而直接指定具体的数据内容. (编译器会根据 {} 中元素个数来确定数组的长度)
T[] 数组名 = new T[] {data1,data2,data3};
T[] 数组名 = {data1,data2,data3};
null
null 表示一个无效的内存位置, 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException 异常
引用本质上就是存了一个地址, 如果该引用指向无效内存, 肯定不能对其进行操作
OOP
OOP (Object Oriented Program) 面向对象语言
面向对象是解决问题的一种思路, 主要依靠对象之间的交互完成一件事情
this
this 引用指向当前对象 (成员方法运行时, 指代调用该成员方法的对象)
this 是 “成员方法” 的第一个隐藏的参数. 编译器会自动传递. 在成员方法运行时, 编译器会负责将调用成员方法的对象的引用, 传递给该成员方法. this 负责接收
局部变量在使用时必须初始化, 而成员变量可以不用
new 一个对象的时候 :
- 检测对象对应的类是否加载了, 如果没有, 则加载该类 (类加载机制)
- 为对象分配内存空间
- 处理并发安全问题 (JVM 保证, 多线程下同时申请对象, 不同对象分配内存不会出现冲突 )
- 初始化所分配的空间 (赋初始值)
- 设置对象头信息
- 调用构造方法, 给对象中的各个成员赋值
封装
封装 : 将数据和数据操作的方法有机结合, 隐藏对象的属性和实现细节. 仅对外公开接口来和对象进行交互
Java 中通过类和访问权限来实现封装
访问限定符
protected 主要用于继承中
软件包
为了更好的管理对象, 把多个类收集在一起称为一组, 称为软件包 (类似于目录)
Java 中的包, 是对类, 接口等的封装机制的体现, 是一种对类或者接口等的很好的组织方式
静态方法特性
- 不属于某个具体的对象, 是类方法
- 可以通过对象调用, 也可以通过
类名.静态方法名( ... )
来调用 - 不能在静态方法中访问任何非静态成员变量
- 不能再静态方法中调用任何非静态方法. 因为非静态方法有 this 参数, 在静态方法中调用时无法传递 this 引用
- 静态方法无法重写, 不能用来实现多态
代码块
分类:
- 普通代码块 - 方法中
- 构造块 - 类中, 对象实例代码块
- 静态块 - 类中, static 定义的代码块
- 同步代码块
- 静态代码块不管生成多少个对象, 只会生成一次
- 静态代码块在 JVM 加载类时, 开辟空间并初始化
- 一个类中的多个静态代码块, 在编译时, 编译器会按照定义的先后次序依次执行 (合并成一个静态代码块)
- 实例代码块只有在创建对象时才会执行
内部类
内部类也是封装的一种体现
内部类和外部类共用同一个 java 源文件, 但是经过编译器 (javac) 编译后, 内部类会生成单独的字节码文件
继承
继承 : 共性提取, 代码复用
super(): 默认调基类, 无参构造方法
super.func( … ) : 调用基类重写前的方法
Java 不支持多继承
继承情况下的代码块之间的执行顺序
- 父类静态代码块 - 只执行一次
- 子类静态代码块 - 只执行一次
- 父类实例代码块
- 父类构造方法
- 子类实例代码块
- 子类构造方法
final
final 修饰变量或字段 : 不能被修改
final 修饰类 : 不能被继承
final 修饰方法 : 不能被重写
多态
- 继承体系下
- 子类必须对父类中的方法进行重写
- 通过父类的引用调用重写方法
- 静态绑定 / 前期绑定 / 早绑定 : 在编译时, 根据用户所传递实参类型就确定了具体调用哪个方法
- 动态绑定 / 后期绑定 / 晚绑定 : 在编译时, 不能确定方法的行为, 需要等到程序运行时, 才能够确定具体调用哪个类的方法
- 向上转型 : 创建一个子类对象, 将其当成父类对象来使用.
父类类型 对象名 = new 子类类型( );
优点 : 让代码实现更简单灵活
缺点: 不能掉应道子类特有的方法 - 向下转型 : 和向上转型对应, 类似强转的东西
(子类类型)父类实例
抽象类
extend abstract
抽象类包括
- 普通属性
- 普通方法
- 抽象方法
- 构造方法
- 抽象类不能实例化对象
- 抽象类不能被 private 修饰
- 抽象类必须被继承
- 抽象类中不一定含抽象方法, 但有抽象方法的类一定是抽象类
- 抽象类中构造方法仅供子类创建对象时, 初始化父类的成员变量使用
抽象类的作用 : 加一层编译器校验, 子类的工作必须由子类完成!
接口
implement interface
一个类可以实现多个接口, 接口之间可以多继承
-
接口不可直接 new
-
接口中每个方法都是 public 的抽象方法 (
public abstract
- 隐式指定) -
接口中的变量, 被隐式指定为
public abstract final
修饰 -
接口中不能有静态代码块和构造方法
-
JDK8中, 接口中可包含
default
修饰的方法 -
Array.sort();
Comparable
接口, 重写compareTo()
方法 -
clone();
Cloneable
接口 -
所有类的公共父类 :
Object
类toString(); equals(); hashcode();
String 不可变
不可变优点
- 方便实现字符串对象池
- 不可变对象是线程安全的
- 不可变对象梗方便缓存 hashcode, 作为 key 时可以更高效保存到 HashMap 中
String 类中的字符时间保存在内部维护的 value 数组中
- String 类被 final 修饰, 表明 String 类不可继承
- value 被 final 修饰, 表明 value 本身的值不能改变 (不能将引用指向其他字符数组), value 中的值是一个地址, 该地址对应的那片空间中的内容是可以改变的
对 String 类型对象的修改, 会创建新对象
String, StringBuffer, StringBuilder
- String 的内容不可修改. StringBuffer, StringBuilder 的内容是可以修改的
- String 类线程安全
StringBuffer 采用同步处理, 线程安全
StringBuilder 未采用同步处理, 线程不安全
常量池
Java 为 8中基本数据类型和 String 类都提供了常量池
字符串常量池在 JVM 中是 StringTable 类, 实际是一个固定大小的 HashTable
String.intern()
: 手动将创建的 String 对象添加到常量池中
Throwable
Throwable : 异常体系的顶级类
Error : 指 Java 虚拟机无法解决的严重问题
- eg: JVM 内部错误, 资源耗尽 …
Exception : 异常产生后程序员可通过代码进行处理
- 编译时异常 (受检查异常)
- 运行时异常(非受检查异常)
throw & throws
- throw 手动抛异常
- throws 向上层代码抛异常
自定义异常
- 继承自 Exception, 默认是受检察异常
- 继承自 RuntimeException, 默认是非受检查异常