1、基础运算
byte b1 = 10;
byte b2 = 20;
// byte b3 = b1 + b2; // 该行报错,因为byte类型参与算术运算会自动提示为int,int赋值给byte可能损失精度
int i3 = b1 + b2; // 应该使用int接收
byte b3 = (byte) (b1 + b2); // 或者将结果强制转换为byte类型
-------------------------------
int num1 = 10;
double num2 = 20.0;
double num3 = num1 + num2; // 使用double接收,因为num1会自动提升为double类型
2、进制转换
二进制:数值前面以0b开头,b大小写都可以。
八进制:数值前面以0开头。
十六进制:数值前面以0x开头,x大小写都可以。
3、包装类
基本数据类型 | 包装类 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
4、枚举
格式
public enum s {
枚举项1,枚举项2,枚举项3;
}
特点
- 所有枚举类都是Enum的子类
- 我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
- 每一个枚举项其实就是该枚举的一个对象
- 枚举也是一个类,也可以去定义成员变量
- 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
- 枚举类可以有构造器,但必须是private的,它默认的也是private的。
- 枚举项的用法比较特殊:枚举("");
- 枚举类也可以有抽象方法,但是枚举项必须重写该方法
方法名 | 说明 |
String name() | 获取枚举项的名称 |
int ordinal() | 返回枚举项在枚举类中的索引值 |
int compareTo(E o) | 比较两个枚举项,返回的是索引值的差值 |
String toString() | 返回枚举常量的名称 |
static <T> T valueOf(Class<T> type,String name) | 获取指定枚举类中的指定名称的枚举值 |
values() | 获得所有的枚举项 |
5、注解
格式
public @interface 注解名称 {
public 属性类型 属性名() default 默认值 ;
}
元注解名 | 说明 |
@Target | 指定了注解能在哪里使用 |
@Retention | 可以理解为保留时间(生命周期) |
@Inherited | 表示修饰的自定义注解可以被子类继承 |
@Documented | 表示该自定义注解,会出现在API文档里面。 |
6、代码块
局部代码块
位置: 方法中定义
作用: 限定变量的生命周期,及早释放,提高内存利用率
构造代码块
位置: 类中方法外定义
特点: 每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行
作用: 将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性
静态代码块
位置: 类中方法外定义
特点: 需要通过static关键字修饰,随着类的加载而加载,并且只执行一次
作用: 在类加载的时候做一些数据初始化的操作
7、接口
常量
public static final
抽象方法
public abstract
默认方法(Java 8)
静态方法(Java 8)
私有方法(Java 9)
默认方法(Java 8)
格式
public default 返回值类型 方法名(参数列表) { }
作用
解决接口升级的问题
范例
public default void show3() {
}
注意事项
- 默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字
- public可以省略,default不能省略
- 如果实现了多个接口,多个接口中存在相同的方法声明,子类就必须对该方法进行重写
私有方法
格式:
private 返回值类型 方法名(参数列表) { }
注意事项
- 默认方法可以调用私有的静态方法和非静态方法
- 静态方法只能调用私有的静态方法
8、继承
继承中变量的访问,采用就近原则,子类局部->子类成员->父类成员
继承中成员方法的访问,采用就近原则,子类成员->父类成员
修饰符 | 同类 | 同包无关类 | 不同包子类 | 不同包无关类 |
private | v | |||
default | v | v | ||
protected | v | v | v | |
public | v | v | v | v |
9、抽象类
1、抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
2、抽象类不能实例化
3、抽象类可以有构造方法
4、抽象类的子类
要么重写抽象类中的所有抽象方法
要么是抽象类
10、多态
什么是多态
同一个对象,在不同时刻表现出来的不同形态
多态的前提
- 要有继承或实现关系
- 要有方法的重写
- 要有父类引用指向子类对象
成员访问特点
成员变量
编译看父类,运行看父类
成员方法
编译看父类,运行看子类
11、内部类
内部类的访问特点
-
内部类可以直接访问外部类的成员,包括私有
-
外部类要访问内部类的成员,必须创建对象
成员内部类
-
成员内部类的定义位置
在类中方法,跟成员变量是一个位置 -
外界创建成员内部类格式
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
举例:Outer.Inner oi = new Outer().new Inner();
- 私有成员内部类
将一个类,设计为内部类的目的,大多数都是不想让外界去访问,所以内部类的定义应该私有化,私有化之后,再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用。
示例代码:
class Outer {
private int num = 10;
private class Inner {
public void show() {
System.out.println(num);
}
}
public void method() {
Inner i = new Inner();
i.show();
}
}
- 静态成员内部类
静态成员内部类访问格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
静态成员内部类中的静态方法:外部类名.内部类名.方法名();
局部内部类
-
局部内部类定义位置
局部内部类是在方法中定义的类 -
局部内部类方式方式
局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
示例代码
class Outer {
private int num = 10;
public void method() {
int num2 = 20;
class Inner {
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
Inner i = new Inner();
i.show();
}
}
匿名内部类
-
匿名内部类的前提
存在一个类或者接口,这里的类可以是具体类也可以是抽象类 -
匿名内部类的格式
格式:new 类名 ( ) { 重写方法 } new 接口名 ( ) { 重写方法 } -
匿名内部类的本质
本质:是一个继承了该类或者实现了该接口的子类匿名对象 -
匿名内部类的细节
匿名内部类可以通过多态的形式接受
Inter i = new Inter(){
@Override
public void method(){
}
}
匿名内部类直接调用方法
interface Inter{
void method();
}
class Test{
public static void main(String[] args){
new Inter(){
@Override
public void method(){
System.out.println("我是匿名内部类");
}
}.method(); // 直接调用方法
}
}
12、Lambda表达式
格式:
(形式参数) -> {代码块}
-
形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
-
->:由英文中画线和大于符号组成,固定写法。代表指向动作
-
代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
组成Lambda表达式的三要素:
形式参数,箭头,代码块
省略的规则
-
参数类型可以省略。但是有多个参数的情况下,不能只省略一个
-
如果参数有且仅有一个,那么小括号可以省略
-
如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
Lambda表达式的使用前提
-
使用Lambda必须要有接口
-
并且要求接口中有且仅有一个抽象方法
13、异常
编译时异常
-
都是Exception类及其子类
-
必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常
-
都是RuntimeException类及其子类
-
无需显示处理,也可以和编译时异常一样处理