1.final关键字

1.

首先补充一个地方:

class前面如果不加任何修饰符,则默认为default

显示这段代码输出结果:

分析这段代码:

输出结果如下:

fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=13 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=1 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=1 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=9 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=8 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=0 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18
fd1:i4=15 ,INT_5 =  18

fd2:i4=2 ,INT_5 =  18

可以得知INT_5=18是一直不会去发生改变的,来看下是如何定义的:

再来看一下i4是如何定义的:

但是为什么fd2的i4是一直变化的,但是fd1是一直不变的

永不改变的编译常量:编译期常量定义,根据惯例,即是static又是final域的也就是编译期常量。

不能因为数据是final的就认为在编译时可以知道他的值,运行时使用rand函数进行随机生成数值进行初始化i4和INT_5就说明了这点;

在数值部分,也定义了静态和非静态的区别:

次区别只有在数值运行时被初始化后才会被显现,static是静态的,因此因此INT_5的值是唯一的,是不可以通过创建第二个finaldata对象而加以改变的,因为他是static的,在装载时已经被初始化的了,但是不是每次创建对象时都会进行初始化操作。

v1到vAL_3说明了final的引用意义,

不能因为v2是final的,就认为他是无法改变他的值,他是一个引用,final意味着无法将v2再次指向一个新的对象:

数组定义如下:

其中a是数组对象:

由此可以得知final是可以改变的但是不可以指向新的对象,佐证如下:

final定义的变量可以在同一个对象的情况下被改变,但是如果换了一个对象,那么就是不能再赋予新的值的,作用域是一个对象内部,

但是作用域即是static又是final的则是编译产量,因此是存在于整个生命周期的,不可以轻易被改变的。

完整验证代码如下,可以复制拿去验证:

import java.util.Random;

public class finalData {
    private static Random rand=new Random(47);
    private String id;
    public finalData(String id){  // 定义一个构造方法
     this.id=id;
    }
    private final int Valueone=9;
    private static final int VALUE_TWO=99;
    //以上两个都带有final,因此可以用作编译期常量,区别并不是很大
    private static final int VALUE_THREE=39;
    /**上面一行是常用的用于定义编译期常量的写法,定义为public表示可以为包之外所用,
     * 定义为static,则强调只有一份
     * 定义为final,则说明他是一个常量
     * 带有恒定初始值也就是编译常量:
     * 根据惯例,编译常量也就是即是final域又是static域的。
     */
    private final int i4=rand.nextInt(20);
    static final int INT_5=rand.nextInt(20);
    private Value v1=new Value(11);
    private final Value v2=new Value(22);
    private static  final  Value v3=new Value(33);
    private final int[] a={1,2,3,4,5,6,7};
    public String toString(){
        return id+":"+"i4="+i4+" ,INT_5 =  "+INT_5;
    }
    public static void main(String[] args){
   finalData fd1=new finalData("fd1");
   //fd1.Valueone++;//调用的时候发现会有错误,  private final int Valueone=9;
        fd1.v2.i++;//将i中值自增1,看看是否会变成23
        fd1.v1=new Value(9);//看下将v1的参数从11改成9会不会成功   private Value v1=new Value(11);//这个可以的运行无错误
        for(int i=0;i<fd1.a.length;i++){//取fd1类中数组的长度作为循环的次数
            fd1.a[i]++; //对象的持续性变化
            System.out.println("验证fd1.a[i]++等于  =="+fd1.a[i]++);
//            fd1.v2=new Value(0); //Error:(28, 16) java: 无法为最终变量v2分配值
//            fd1.v3=new Value(1); //Error:(29, 16) java: 无法为最终变量v3分配值
//            fd1.a=new int[3]; //Error:(30, 16) java: 无法为最终变量a分配值
            System.out.println(fd1);
            System.out.println(fd1);
        finalData fd2=new finalData("fd2");
            System.out.println(fd1);
            System.out.println(fd2);
        }

    }
}

猜你喜欢

转载自blog.csdn.net/qq_35561207/article/details/84327763
今日推荐