解析java中的final关键字
1 含义
final意思是终结的,在java中的解释就是最终版本。可以用来修饰类、变量、方法。
2 为什么需要它
当我们不想类被继承时,可以使用final修饰该类,如java中的String类
当我们不想方法被重写时,可以使用final修饰该方法,如java的Math类中的abs方法
当我们**不想变量被赋值后能被修改,**可以使用final修饰该变量,如Math类中的PI常量
3 如何使用它
3.1 修饰变量
3.1.1 局部变量
a 语法
权限修饰符列表 final 变量数据类型 变量名;
b.使用规则
定义时,可以不用赋值,但是使用前一定得赋值,不然编译就会报错
错误示例代码
package Work03;
public class Test {
public static void main(String[] args) {
final int a;
System.out.println(a);
}
}
错误示例代码运行截图
仅能赋值一次,且赋值后值不能被修改
错误示例代码
package Work03;
public class Test {
public static void main(String[] args) {
final int a=1;
System.out.println(a++);
}
}
错误示例代码截图
3.1.2 成员变量(属性)
a 语法
权限修饰符列表 final 变量数据类型 变量名;
b 使用规则
定义时,可以不先给值,但是一定要通过构造方法给它赋值,因为被final修饰的变量不会通过无参构造赋上默认值。
正确示例代码
package Work03;
public class Test {
public static void main(String[] args) {
System.out.println(new A().a);
}
}
class A{
final int a;
public A() {
a=10;
}
}
正确代码运行截图
3.1.3 特殊的变量-----常量
a 语法
public static final 常量数据类型 常量名=数值;
b 使用规则
b.1 常量的定义不能写在方法里面
因为static修饰只能修饰成员变量,不能修饰局部变量
b.2 常量后面的数值必须与常量数据类型保持一致
b.3 常量名的所有字母都大写,这是一种规范
b.4 常量一经定义就必须在定义里面给它附上值,不允许通过构造方法去赋值
错误代码示例
package Work03;
public class Test {
public static void main(String[] args) {
}
}
class A{
public static final int a;
public A() {
a=10;
}
}
错误代码示例截图
3.1.4 特殊的变量-----引用数据类型
a 语法
public final 引用数据类型(类名) 对象名(引用);
b 使用规则
修饰引用数据类型时,不能改变的是指向的那个内存地址,而内存地址里面的属性值是可以修改的
错误示例代码
package Work03;
public class Test {
public static void main(String[] args) {
A a=new A();
a.b=new B();
}
}
class A{
public final B b=new B();
public A() {
}
}
class B{
String name;
}
错误示例代码截图
正确示例代码
package Work03;
public class Test {
public static void main(String[] args) {
A a=new A();
System.out.println("修改前: name的值为:"+a.b.name);
a.b.name="张三";
System.out.println("修改前: name的值为:"+a.b.name);
}
}
class A{
public final B b=new B();
public A() {
}
}
class B{
String name;
}
正确示例代码运行截图
3.1.5 总结
a 被final修饰的变量只能赋值一次;
b 修饰成员变量时可以通过构造方法手动赋值
c 修饰常量时必须一经定义就赋值,但若是引用数据类型,就可以通过构造方法或者实例代码块将内存里面的属性值进行更改。
c.1 正确示例代码
package Work03;
public class Test {
public static void main(String[] args) {
A a=new A();
System.out.println("修改前: name的值为:"+A.b.name);
A.b.name="李四";
System.out.println("修改前: name的值为:"+A.b.name);
}
}
class A{
public static final B b=new B();
public A() {
}
}
class B{
String name;
}
c.2 正确示例代码运行截图
d.常量不要随便用
比如说:工商银行卡类里面有一个属性卡号,它在对象初始化后就不能修改了,但是它不能设置为常量,因为它是对象独有的,你不想别人通过类名.属性去调用,它里面的开户行每个对象都是一样的,就可以设置为常量
3.2 修饰方法
3.2.1 语法
权限修饰符 final 返回值类型 方法名(形参列表){
//方法体内容
}
3.2.2 使用规则
a 被final修饰的方法不可以被重写
b 使用场景:不希望子类有差异化
示例代码(Object类里面的)
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
3.3 修饰类
3.3.1 语法
权限修饰符 final class 类名{
//类体的内容
}