Java学习之final修饰符(成员变量,局部变量,基本与引用类型变量,方法和类)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43271086/article/details/91470725

本文主要讲述内容:

  1. final成员变量

  2. final局部变量

  3. final修饰基本类型变量和引用类型变量的区别

  4. “宏替换”的final

  5. final方法

  6. final类

1.final成员变量

final指定的成员变量必须由程序员显式的进行指定初始值

归纳总结:final修饰的类变量,实例变量指定初始值的位置如下。

类变量:必须再静态初始化中指定初始值或声明该类变量的时候指定初始值,而且必须是其中的一种

实例变量:必须在非静态初始化块,声明该实例变量或者构造器中指定初始化,必须是其中的一个

代码如下:

public class FinalVariableTest {
    final int a=6;
    final String str;
    final int c;
    final static double d;
    //final char ch;
    //普通变量初始化块
    {
        str="hello";
        //下面语句运行会发生错误
        //a=9;
    }
    //静态变量初始化块
    static {
        d=5.6;
    }
    public FinalVariableTest(){
        //在构造器中设置初始值
        c=5;
    }
    public  void changeFinal(){
        //不能在普通方法中为final修饰的成员变量赋值
        //d=1.2;
        //不能在普通方法中为final设置的变量设置初始值
        //ch='a';
    }
public static void main(String[] args) {
        FinalVariableTest ft=new FinalVariableTest();
        System.out.println(ft.a);
        System.out.println(ft.c);
        System.out.println(ft.str);
        System.out.println(ft.d);
        new FinalVariableTest();
    }

有如果在初始化之前访问由final修饰的变量,显然这是不可能的,但是Java提供方法对他可以进行访问

代码如下:

//final修饰符的访问机制
    final int age;
    {
        //在没有进行显式初始化之前进行访问会引起错误
        //System.out.println(age);
        //可以通过方法对final修饰的成员变量进行访问,但是这里的成员变量还没有进行显式初始化,所以输出是0
        printAge();
        //进行显式初始化之后,输出为6
        age=6;
        System.out.println(age);
    }
    public void printAge(){
        System.out.println(age);
        }

2.局部变量

局部变量包括局部变量和形参

因为系统不会对局部变量进行初始化,必须由程序员进行显式初始化。因此使用final修饰的局部变量。既可以在定义是默认初始值也可以不指定初始值。

代码展示:

public class FinalLocaVariable {
    public void test(final int a){
        //不能对final修饰的形参进行赋值操作
        //a=5;
    }

    public static void main(String[] args) {
        final String str="hello";
        //str="java";
        final double d;
        //初次赋值是正确的
        d=5.6;
        //再次赋值将发生错误
        //d=6;
        System.out.println(str);
        System.out.println(d);
    }
}

3,final修饰基本类型变量和引用类型变量的区别

final修饰基本类型变量时,如果该变量已经进行了初始化,则该变量的值不能再改变

final修饰引用类型变量的时候,引用指向的时某个对象的地址,所以该地址不能改变,但是对象可以发生变化(他一直在那,但是他变了,哈哈)

代码展示:

import java.lang.reflect.Array;
import java.util.Arrays;

public class Person {
    private int age;
    //构造一个无参的构造器
    public Person(){};
    //重载构造器
    public Person(int age){
        this.age=age;
    }
    public void setAge(int age){
        this.age=age;
    }
    public int getAge(){
        return age;
    }

    public static void main(String[] args) {
        //设置一个final修饰的数组
        final int[] iArr={5,6,12,9};
        //输出这个数组
        System.out.println(Arrays.toString(iArr));
        //对数组进行排序
        Arrays.sort(iArr);
        //排序后输出
        System.out.println(Arrays.toString(iArr));
        //改变数组中的只的置的值,这个可以做到,原因是final修饰不能改变的是他的地址,但是它引用的对象则可以进行改变
        iArr[2]=-8;
        System.out.println(Arrays.toString(iArr));
        //下面这句话就会出现运行错误,因为地址发生了变动
        //iArr=null;
        //下面的原因与上面类似
        final Person p=new Person(45);
        p.setAge(23);
        System.out.println(p.getAge());
        //p=null;
        //进行宏替换的final变量
        final int a=5;
        //这里再运行过程中直接将a转化成5,这就是“宏变量”,必须再定义是才有效果
        System.out.println(a);
    }
}

4,“宏替换”的final

如果一个final满足这三个条件,那么他就相当于一个直接量

  1. 使用final进行修饰
  2. 在定义final变量的时候进行了初始化。
  3. 该初始值在编译的时候就可以确定下来

是不是看出来一个很重要的点,那就是在定义时就进行初始化

代码展示:

//进行宏替换的final变量
        final int a=5;
        //这里再运行过程中直接将a转化成5,这就是“宏变量”,必须再定义是才有效果
        System.out.println(a);

系统在接下来的就直接在能用到a的地方进行替换

5.final方法

final修饰的方法不能被重写,如果父类的方法不想被子类所重写,可以使用final进行修饰

则下面的代码运行会发生错误

public class FinalMethod(){
    public void test(){}
}

class sub extends FinalMethod(){
    public void test(){}
}

错误原因:因为重写了父类的final方法引发错误

重点来了,对于一个private修饰的方法,因为本身就不能被子类访问,所以子类无法进行重写,在加上final之后,如果子类“重写”这个方法的时候相当于重新定义一个方法,跟父类没有关系。

6.final类

单纯说明就是不可以有子类

猜你喜欢

转载自blog.csdn.net/weixin_43271086/article/details/91470725