final 关键字
final代表最终、不可改变的
可以修饰一个类
修饰一个方法
修饰一个局部变量
修饰一个成员变量
1.修饰一个类时,格式:
1 | public final class 类名称 { |
含义:final类为太监类,不能有子类
注意:一个类为final,所有成员方法都无法进行覆盖重写
2.修饰一个方法时,格式:
修饰符 final 返回值类型 方法名称(参数列表) {
// 方法体
}
含义:最终方法,不能被覆盖重写
注意:对类、方法来说,abstract和final不能同时使用,矛盾
3.修饰一个局部变量
格式:只能赋值一次,不可改变
对基本类型来说,不可变说的是变量中的数据不可变
格式:final 数据类型 变量名称 = 字面量;
对引用类型来说,不可变说的是的变量中的地址值不可变
例如:final Student stu1 = new Student(“高圆圆”);
stu1 = new Student(“高圆”); // 错误,地址值不能变
stu1.setName(“高”); // 正确
stu1的地址值不能变,但地址所指向的对象可以改变
4.修饰成员变量
含义:如果使用final修饰,那么这个变量也不可变
注意:
- 由于成员变量具有默认值,所以用了final之后之后一定要手动赋值
- 对于final成员变量,那么使用直接复制,要么通过构造方法赋值(2选1)
- 必须保证类中所有重载的构造方法,都会最终会对final的成员变量进行赋值
权限
1.java中四种权限修饰符
2.java中只要不是在一个包中就要导包。一个包里面创建一个子包,也不属于同一个包。
内部类
如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类
分类:
- 成员内部类
- 局部内部类(包含匿名内部类)
注意:内用外,随便访问,外用内,需要内部类对象。
成员内部类
· 定义格式:
1 | 修饰符 class 外部类名称 { |
编译后,内部类名称为”外部类名称$内部类名称.class” ,所以定义类名称时候虽然标识符能用下划线和$符号,尽量不要用$符号,以免产生误解。
使用:
- 间接方式:在外部类的方法中,(创建内部类对象),使用内部类;然后main只是调用外部类的方法
- 直接方式:
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】
· 先有外部类才能有内部类
· 如果出现了重名对象,格式为:外部类名称.this.外部类成员变量名
局部内部类
如果一个类是定义在一个方法内部的,出来这个方法在外面就不能使用了。
定义格式:
1 | 修饰符 class 外部类名称 { |
· 局部内部类,如果希望访问所在方法的局部变量,这个局部变量必须是【有效final】的。(Java8开始,只要保证变量未变,final关键字也可以省略)
原因:(生命周期问题)
- new出来的对象在堆当中
- 局部变量是跟着方法走的,在栈当中
- 方法运行结束之后,立刻出栈,局部变量就会立刻消失
- 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失
- 当局部内部类中想要用方法的局部变量,只要保证值不变,就直接复制一份进来成常量,之后就用常量池里的常量
定义一个类的时候,权限修饰符规则:
- 外部类:public / (default)
- 成员内部类:public / protected / (default)/ private
- 局部内部类:什么都不能写
匿名内部类
如果接口的实现类,或者是父类的子类,只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改用【匿名内部类】
· 定义格式:
1 | 接口名称 对象名 = new 接口名称() { |
· 解析:
- new代表创建对象的动作
- 接口名称是匿名内部类需要实现哪个接口
- {···}才是匿名内部类的内容
· 注意: - 匿名内部类,在【创建对象】的时候,只能使用唯一一次
- 匿名对象,在【调用方法】的时候,只能调用唯一一次,要多次必须起名
- 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
所以匿名内部类,匿名对象不是一回事
引用类型用法总结
- 类可以作为成员变量类型
- 接口也可以作为成员变量类型
- 接口作为方法的参数和返回值