JAVA

Java基础 final关键字用法

转载:https://blog.csdn.net/u012514113/article/details/129217902

一. 概述


final关键字代表最终,不可改变的.

常见有5种用法,我们来归纳总结一下:

  • 1. 用来修饰一个类
  • 2. 用来修饰一个方法
  • 3. 用来修饰成员变量
  • 4. 用来修饰局部变量
  • 5. 用来修饰方法参数

二. final饰修类


如果声明一个类为final类,  那么这个类就是最终类,不能被继承

public final class ParentClass {
    public void happy() {
        System.out.println("高兴");
    }
}

当写一个类去继承它的时候

    public class ChildClass extends ParentClass{
     
    }

就会提示如下错误:

  注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写.

三. final修饰方法


当final用来修饰一个方法的时候,这个方法就是最终方法,那么很明显就是说不能被覆盖重写。

public class ParentClass {
 
    public void happy() {
        System.out.println("高兴");
    }
    
    //用final关键字修饰的方法
    protected final void play(){
        System.out.println("开心的玩耍");
    }
 
}

我们在继承类中去看下 play()方法是否可以被override

 也是报错,说明 final修饰的方法,是一个最终方法,不能被子类去覆盖重写.

四. final修饰成员变量


在java中,成员变量一般都有默认值, 比如 int 型变量,默认值为0     boolean型变量默认值为false

String型变量,默认值为null

我们来看上面的例子, 3个同样类型的 int型 成员变量, number temp 默认值都是0 , 写和没写都没有报错. 但是加上final之后的num变量,没有初始化就报错.

总结一: 由于成员变量具有默认值,但是用了final关键字修饰之后必须要手动赋值初始化值.

我们再看一个例子

总结二: 对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可被改变

五. final修饰局部变量


对于基本类型来说,不可变说的是变量当中的数据不可改变;

请看如下例子:

对于引用类型来说,不可变指的是变量当中的地址值不可改变

我们再来看下个例子,

Student为一个普通的javabean类

 
    private String name;
 
    public Student() {
    }
 
    public Student(String name) {
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

第一种情况,没有final修饰的测试类

public class FinalVarTest {
 
    public static void main(String[] args) {
        Student student1 = new Student("勒布朗.詹姆斯");
        System.out.println(student1); //打印内存地址
        System.out.println(student1.getName());
 
        student1 = new Student("斯蒂芬.库里");
        System.out.println(student1); //打印内存地址
        System.out.println(student1.getName());
    }
}

打印结果如下:

 
com.finaltest.Student@4aa298b7   //内存地址
勒布朗.詹姆斯
 
 
com.finaltest.Student@7d4991ad  //内存地址
斯蒂芬.库里

输出结果:内存地址不同

第二种情况: 使用final修饰测试类

 若用final修饰,地址值不可以被改变,否则直接报错.

地址值虽然不能变,但是内容可以变(地址所指向的对象的属性可以被该变)。

请看如下例子:

public class FinalVarTest {
 
    public static void main(String[] args) {
        //使用final修饰的对象
        final Student student2 = new Student("詹姆斯.哈登");
        System.out.println(student2); //打印内存地址
        System.out.println(student2.getName());
 
        student2.setName("安东尼.戴维斯");
        System.out.println(student2); //打印内存地址
        System.out.println(student2.getName());
    }
}

打印结果如下:

com.finaltest.Student@4aa298b7
詹姆斯.哈登
 
com.finaltest.Student@4aa298b7
安东尼.戴维斯

两者的内存地址是相同的,但是名字(属性)是可以修改的.

六. final修饰参数


在方法参数前面加final关键字就是为了防止数据在方法体中被修改。

主要分两种情况:第一,用final修饰基本数据类型;第二,用final修饰引用类型。

第一种情况,修饰基本类型(非引用类型)。这时参数的值在方法体内是不能被修改的,即不能被重新赋值。否则编译就通不过。例如:

第二种情况,修饰引用类型。这时参数变量所引用的对象是不能被改变的。作为引用的拷贝,参数在方法体里面不能再引用新的对象。否则编译通不过。例如:

但是对于引用,如果我是这样(也就是引用对象的地址不能改变,但是对象中的内容是可以改变的),则不会报任何错,完全能编译通过。

public class FinalVarTest {
 
    public static void main(String[] args) {
        String[] var = {"张三","李四", "王五"};
        valid(var);
    }
 
    public static void valid(final String[] ag){
       ag[2]= "赵六";
       for(int i=0; i<ag.length; i++) {
           System.out.println(ag[i]);
       }
    }
}

编译通过,打印如下:

    张三
    李四
    赵六