一、final 关键字
1.1 概述
学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能随意的继承 API 中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java提供了 final
关键字, 用于修饰不可改变内容。
- final: 不可改变。可以用于修饰类、方法和变量。
- 类:被修饰的类,不能被继承。
- 方法:被修饰的方法,不能被重写。
- 变量:被修饰的变量,不能被重新赋值。
1.2 使用方式
1.2.1 修饰类
-
格式
public final class 类名称 { // ... }
-
含义:当前这个类不能有任何的子类。(太监类)
注意:一个类如果是
final
的,那么其中所有的成员方法都无法进行覆盖重写(因为没儿子。)
1.2.2 修饰方法
-
格式
修饰符 final 返回值类型 方法名(参数列表){ //方法体 }
-
含义:当前这个方法不能被重写。
注意:重写被
final
修饰的方法,编译时就会报错
1.2.3 修饰变量
-
局部变量–基本类型
基本类型的局部变量,被
final
修饰后,只能赋值一次,不能再更改。【即 一次赋值,终生不变】代码如下:
public class FinalDemo1 { public static void main(String[] args) { // 声明变量,使用final修饰 final int a; // 第一次赋值 a = 10; // 第二次赋值 a = 20; // 报错,不可重新赋值 // 声明变量,直接赋值,使用final修饰 final int b = 10; // 第二次赋值 b = 20; // 报错,不可重新赋值 } }
总结:对于
final
修饰的基本类型,只要保证有唯一 一次赋值即可。思考,如下两种写法,哪种可以通过编译?
-
写法一:
final int c = 0; for (int i = 0; i < 10; i++) { c = i; System.out.println(c); }
-
写法二:
for (int i = 0; i < 10; i++) { final int c = i; System.out.println(c); }
根据
final
的定义,写法1报错!写法2,为什么通过编译呢?因为每次循环,都是一次新的变量c,故每次 变量c 都只赋值一次。这也是我们需要注意的地方。 -
-
局部变量–引用类型
引用类型的局部变量,被
final
修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改。代码如下:
public class FinalDemo2 { public static void main(String[] args) { // 创建 User 对象 final User u = new User(); // 创建 另一个 User对象 u = new User(); // 报错,指向了新的对象,地址值改变。 // 调用setName方法 u.setName("张三"); // 可以修改 } }
总结:
- 对于基本类型来说,不可变说的是变量当中的数据不可改变
- 于引用类型来说,不可变说的是变量当中的地址值不可改变
-
成员变量
对于成员变量来说,如果使用
final
关键字修饰,那么这个变量也照样是不可变。-
由于成员变量具有默认值,所以用了
final
之后必须手动赋值,不会再给默认值了。 -
必须保证类当中所有重载的构造方法,都最终会对
final
的成员变量进行赋值。 -
对于 final 修饰的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
-
直接赋值
public class User { final String USERNAME = "张三"; private int age; }
-
构造方法赋值
public class User { final String USERNAME ; private int age; public User(String username, int age) { this.USERNAME = username; this.age = age; } }
被
final
修饰的常量名称,一般都有书写规范,即所有字母都大写。 -
-
二、权限修饰符
2.1 概述
在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,
-
public:公共的。
-
protected:受保护的
-
default:默认的
-
private:私有的
2.2 不同权限的访问能力
public > protected > (default) > private
public | protected | (default ) | private | |
---|---|---|---|---|
同一类中 | ✔ | ✔ | ✔ | ✔ |
同一包中(子类与无关类) | ✔ | ✔ | ✔ | |
不同包的子类 | ✔ | ✔ | ||
不同包中的无关类 | ✔ |
注意:(default) 并不是关键字
default
,而是根本不写。
可见,public 具有最大权限。private 则是最小权限。
编写代码时,如果没有特殊的考虑,建议这样使用权限:
-
成员变量使用
private
,隐藏细节。 -
构造方法使用
public
,方便创建对象。 -
成员方法使用
public
,方便调用方法。
小贴士:不加权限修饰符,其访问能力与
default
修饰符相同