日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java final修饰的数组_Java基于final修饰数据过程解析

發(fā)布時間:2023/12/14 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java final修饰的数组_Java基于final修饰数据过程解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這篇文章主要介紹了Java基于final修飾數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

final是Java中的一個重要關鍵字,它可以修飾數(shù)據(jù)、方法和類,本篇將從final修飾的數(shù)據(jù)角度對final做出總結。

final修飾的數(shù)據(jù)代表著:永遠不變。意思是,一旦你用final修飾一塊數(shù)據(jù),你之后就只能看看它,你想修改它,沒門。

我們不希望改變的數(shù)據(jù)有下面兩種情況:

永不改變的編譯時常量。

//編譯時知道其值

private final int valueOne = 9;

在運行時(不是編譯時)被初始化的值,且之后不希望它改變。

//在編譯時不能知道其值

private final int i4 = rand.nextInt(20);

設置成常量有啥好處呢?

很簡單,讓編譯器覺得簡單,就是最大的好處。比如把PI設置成final,且給定值為3.14,編譯器自然會覺得這個東西不會再被修改了,是足夠權威的。那么,編譯器就會在運行之前(編譯時)就把這3.14代入所有的PI中計算,這樣在真正運行的時候,速度方面當然會快一點。

有初始值的final域

即聲明為final且當場就給定初始值的域。

private final int valueOne = 9;

final+基本數(shù)據(jù)類型

final修飾的基本數(shù)據(jù)類型變量存儲的數(shù)值永恒不變。

/*基本類型變量*/

//帶有編譯時數(shù)值的final基本類型

private final int valueOne = 9;

private static final int VALUE_TWO = 99;

public static final int VALUE_THREE = 39;

//!false:fd1.valueOne++;

//!false:fd1.VALUE_TWO++;

//!false:fd1.VALUE_THREE++;

康康上面醒目的三句false語句,很好地印證了我們之前說的:數(shù)值不讓改!!!

需要注意的是,按照慣例,下面是定義常量的典型方式:

//典型常量的定義方式

public static final int VALUE_THREE = 39;

public修飾符使其可被用于包之外。

static使數(shù)據(jù)只有一份。

final表示其無法被更改

名稱全為大寫英文字母,以下劃線隔開。

final+引用數(shù)據(jù)類型

我們之前說過,基本類型存數(shù)值,引用類型存地址值。那么既然final+基本數(shù)據(jù)類型不讓改數(shù)值,聰明的我們稍微一聯(lián)想就明白,final+引用數(shù)據(jù)類型就是不讓你改變量存儲實際對象的地址值啦。(也就是不能再讓它指向新的對象,很專一)

private Value v1 = new Value(1);

private final Value v2 = new Value(22);

private static final Value V_3 = new Value(333);

//引用變量并不是常量,存儲地址可以改變

fd1.v1 = new Value(10);

//v2是引用變量,final修飾之后表示地址不能改變,但是實際對象的值是可以改變的

fd1.v2.i++;

//!false:fd1.v2 = new Value(3);

//V_3與v2類似,是靜態(tài)和非靜態(tài)的區(qū)別,下面會說明

fd1.V_3.i++;

//!false:fd1.V_3 = new Value(10);

}

通過例子,確實也證明上面所說,一個以final修飾的引用數(shù)據(jù)類型變量,無法再指向一個新的對象,因為它所存儲的地址值已經(jīng)無法被更改,但是并不影響它指向的實際對象。就拿一個比較典型的引用類型來舉例,我們知道數(shù)組就是一種典型的引用類型,數(shù)組的引用變量存儲的是數(shù)組再堆中的地址,堆中存放的就是數(shù)組每個索引的數(shù)值。

/*引用變量之數(shù)組*/

private final int[] a = {1,2,3,4,5,6};

引用變量a被指定為final,所以它里面的地址值不能再改,也就無法再讓它指向一個新的數(shù)組。

//!false:fd1.a = new int[]{2,3,4,5,6,7};

for (int i = 0; i < fd1.a.length; i++) {

fd1.a[i]++;

但是,它指向的數(shù)組里的每個元素卻可以改動,因為數(shù)組中的元素并沒有任何的限定。

final與static final

private final int i4 = rand.nextInt(20);

static final int INT_5 = rand.nextInt(20);

System.out.println(fd1);//fd1: i4 = 15,INT_518

FinalData fd2 = new FinalData("fd2");

System.out.println(fd2);//fd2: i4 = 13,INT_518

FinalData fd3 = new FinalData("fd3");

System.out.println(fd3);//fd3: i4 = 1,INT_5 = 18

上面示例分別創(chuàng)建了三個不同的對象,對其final 和final static 進行測試。

需要明確的是,兩者都以final修飾,都不能被改變。

三個對象的i4值,沒有用static修飾,不相同且不能改變。

而INT_5的值因為被static修飾,在類加載時已經(jīng)被初始化,不隨對象改變而改變。

空白final域

即聲明為final卻沒有給定初始值的域。

private final String id;//空白final

如果只有上面的這句,編譯器會報錯,因為它沒有初始化。

Variable 'id' might not have been initialized

所以,若定義了空白final域,一定記得在構造器中給它賦值!(必須在域的定義處或者每個構造器中以表達式對final進行賦值,因為系統(tǒng)不會為final域默認初始化)

//在構造器中為空白final域賦初值

public FinalData(){

id = "空白final默認id";

}

public FinalData(String id){

this.id = id;

}

不要試圖在初始化之前訪問域,不然會報錯。

final讓域可以根據(jù)對象的不同而不同,增加靈活性的同時,又保留不被改變的特性。

final修飾的參數(shù)

基本數(shù)據(jù)類型的參數(shù)

類似地,就是傳入的參數(shù)不讓改,只讓讀,這一點很好理解。

public int finalParamTest(final int i){

//!false:i++;

//不讓改,只讓讀

return i+1;

}

但是,我又新增了許多測試,分別定義四種不同的參數(shù)傳入該方法,發(fā)現(xiàn)傳入param0和param1編譯會報錯。(非常疑惑,這部分書上沒提,查了許多資料也沒有理解清楚,希望大牛可以評論區(qū)指點迷津)

/*檢測傳入?yún)?shù)*/

int param0 = 5;

final int param1 = 10;

static final int PARAM_2 = 15;

static int param3 = 20;

//!false:System.out.println(fd1.finalParamTest(param0));

//!false:System.out.println(fd1.finalParamTest(param1));

//non-static field'param1' cannot be referenced from a static context

System.out.println(fd1.finalParamTest(PARAM_2));

System.out.println(fd1.finalParamTest(param3));

/*為什么形參列表里的參數(shù)用final修飾,但是用final修飾的param1無法傳進去,

一定要static修飾?*/

引用數(shù)據(jù)類型的參數(shù)

public void finalReferenceTest(final FinalData fd){

//!false:fd = new FinalData();

//不能再指向新的對象,存儲地址不準變

fd.param0++;

}

還是類似,不可以讓這個引用類型的參數(shù)再指向新的對象,但是可以改變其實際指向?qū)ο蟮闹怠?/p>

最后的最后,下面的代碼是根據(jù)《Thinking in Java》中的示例,結合自己的思想,將各個板塊融合而成的超級無敵測試代碼,沖沖沖!

package com.my.pac16;

import java.util.Arrays;

import java.util.Random;

/**

* @auther Summerday

*/

class Value{

int i;//package access

public Value(int i){

this.i =i;

}

}

/*final域在使用前必須被初始化:定義時,構造器中*/

public class FinalData {

/*檢測傳入?yún)?shù)*/

int param0 = 5;

final int param1 = 10;

static final int PARAM_2 = 15;

static int param3 = 20;

private static Random rand = new Random(47);

private final String id;//空白final

public FinalData(){

id = "空白final默認id";

}

public FinalData(String id){

this.id = id;

}

//帶有編譯時數(shù)值的final基本類型

private final int valueOne = 9;

private static final int VALUE_TWO = 99;

//典型常量的定義方式

public static final int VALUE_THREE = 39;

//在編譯是不能知道其值

private final int i4 = rand.nextInt(20);

static final int INT_5 = rand.nextInt(20);

private Value v1 = new Value(1);

private final Value v2 = new Value(22);

private static final Value V_3 = new Value(333);

private final int[] a = {1,2,3,4,5,6};

@Override

public String toString(){

return id+": "+"i4 = "+i4+",INT_5 = "+INT_5;

}

public int finalParamTest(final int i){

//!false:i++;

//不讓改,只讓讀

return i+1;

}

public void finalReferenceTest(final FinalData fd){

//!false:fd = new FinalData();

//不能再指向新的對象,存儲地址不準變

fd.param0++;

}

public static void main(String[] args) {

FinalData fd1 = new FinalData("fd1");

/*基本類型變量*/

//!false:fd1.valueOne++;

//!false:fd1.VALUE_TWO++;

//!false:fd1.VALUE_THREE++;

/*引用變量*/

fd1.v1 = new Value(10);

fd1.v2.i++

//!false:fd1.v2 = new Value(3);

System.out.println("fd1.v2.i = [" + fd1.v2.i + "]");

//!false:fd1.V_3 = new Value(10);

fd1.V_3.i++;

System.out.println("fd1.V_3.i = [" + fd1.V_3.i + "]");

/*引用變量之數(shù)組*/

System.out.println("before:fd1.a[] = " + Arrays.toString(fd1.a));

/*數(shù)組引用變量a是final修飾,

但是不代表它指向的數(shù)據(jù)值是final,

而是a存儲的地址值不能改變

*/

//!false:fd1.a = new int[]{2,3,4,5,6,7};

for (int i = 0; i < fd1.a.length; i++) {

fd1.a[i]++;

}

System.out.println("after :fd1.a[] = " + Arrays.toString(fd1.a));

/*final 與static final*/

//下面示例分別創(chuàng)建了三個不同的對象,對其final 和final static 進行測試

/*可以發(fā)現(xiàn),三個對象的i4值是隨機生成且不能改變的,且不相同,

而INT_5的值不隨對象改變而改變,因為被static修飾,在類加載時已經(jīng)被初始化*/

System.out.println(fd1);//fd1: i4 = 15,INT_518

FinalData fd2 = new FinalData("fd2");

System.out.println(fd2);//fd2: i4 = 13,INT_518

FinalData fd3 = new FinalData("fd3");

System.out.println(fd3);//fd3: i4 = 1,INT_5 = 18

//!false:System.out.println(fd1.finalParamTest(param0));

//!false:System.out.println(fd1.finalParamTest(param1));

//non-static field'param1' cannot be referenced from a static context

System.out.println(fd1.finalParamTest(PARAM_2));

System.out.println(fd1.finalParamTest(param3));

/*為什么形參列表里的參數(shù)用final修飾,但是用final修飾的param1無法傳進去,

一定要static修飾?*/

System.out.println("fd1.param0 = "+fd1.param0);

fd1.finalReferenceTest(fd1);

System.out.println("fd1.param0 = "+fd1.param0);

}

}

文章如有理解錯誤或敘述不到位,歡迎大家在評論區(qū)加以指正。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

總結

以上是生活随笔為你收集整理的java final修饰的数组_Java基于final修饰数据过程解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。