最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java基于final修飾數(shù)據(jù)過(guò)程解析

 更新時(shí)間:2019年12月18日 08:37:30   作者:天喬巴夏丶  
這篇文章主要介紹了Java基于final修飾數(shù)據(jù)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

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

final是Java中的一個(gè)重要關(guān)鍵字,它可以修飾數(shù)據(jù)、方法和類(lèi),本篇將從final修飾的數(shù)據(jù)角度對(duì)final做出總結(jié)。

final修飾的數(shù)據(jù)代表著:永遠(yuǎn)不變。意思是,一旦你用final修飾一塊數(shù)據(jù),你之后就只能看看它,你想修改它,沒(méi)門(mén)。
我們不希望改變的數(shù)據(jù)有下面兩種情況:

永不改變的編譯時(shí)常量。

//編譯時(shí)知道其值
private final int valueOne = 9;

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

//在編譯時(shí)不能知道其值
private final int i4 = rand.nextInt(20);

設(shè)置成常量有啥好處呢?

很簡(jiǎn)單,讓編譯器覺(jué)得簡(jiǎn)單,就是最大的好處。比如把PI設(shè)置成final,且給定值為3.14,編譯器自然會(huì)覺(jué)得這個(gè)東西不會(huì)再被修改了,是足夠權(quán)威的。那么,編譯器就會(huì)在運(yùn)行之前(編譯時(shí))就把這3.14代入所有的PI中計(jì)算,這樣在真正運(yùn)行的時(shí)候,速度方面當(dāng)然會(huì)快一點(diǎn)。

有初始值的final域

即聲明為final且當(dāng)場(chǎng)就給定初始值的域。

private final int valueOne = 9;

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

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

/*基本類(lèi)型變量*/
//帶有編譯時(shí)數(shù)值的final基本類(lèi)型
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語(yǔ)句,很好地印證了我們之前說(shuō)的:數(shù)值不讓改?。?!

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

//典型常量的定義方式
public static final int VALUE_THREE = 39;
  • public修飾符使其可被用于包之外。
  • static使數(shù)據(jù)只有一份。
  • final表示其無(wú)法被更改
  • 名稱(chēng)全為大寫(xiě)英文字母,以下劃線隔開(kāi)。

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

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

private Value v1 = new Value(1);
private final Value v2 = new Value(22);
private static final Value V_3 = new Value(333);
//引用變量并不是常量,存儲(chǔ)地址可以改變
fd1.v1 = new Value(10);

//v2是引用變量,final修飾之后表示地址不能改變,但是實(shí)際對(duì)象的值是可以改變的
fd1.v2.i++;
//!false:fd1.v2 = new Value(3);

//V_3與v2類(lèi)似,是靜態(tài)和非靜態(tài)的區(qū)別,下面會(huì)說(shuō)明
fd1.V_3.i++;
//!false:fd1.V_3 = new Value(10);
}

通過(guò)例子,確實(shí)也證明上面所說(shuō),一個(gè)以final修飾的引用數(shù)據(jù)類(lèi)型變量,無(wú)法再指向一個(gè)新的對(duì)象,因?yàn)樗鎯?chǔ)的地址值已經(jīng)無(wú)法被更改,但是并不影響它指向的實(shí)際對(duì)象。就拿一個(gè)比較典型的引用類(lèi)型來(lái)舉例,我們知道數(shù)組就是一種典型的引用類(lèi)型,數(shù)組的引用變量存儲(chǔ)的是數(shù)組再堆中的地址,堆中存放的就是數(shù)組每個(gè)索引的數(shù)值。

/*引用變量之?dāng)?shù)組*/
private final int[] a = {1,2,3,4,5,6};

引用變量a被指定為final,所以它里面的地址值不能再改,也就無(wú)法再讓它指向一個(gè)新的數(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ù)組里的每個(gè)元素卻可以改動(dòng),因?yàn)閿?shù)組中的元素并沒(méi)有任何的限定。

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)建了三個(gè)不同的對(duì)象,對(duì)其final 和final static 進(jìn)行測(cè)試。

  • 需要明確的是,兩者都以final修飾,都不能被改變。
  • 三個(gè)對(duì)象的i4值,沒(méi)有用static修飾,不相同且不能改變。
  • 而INT_5的值因?yàn)楸籹tatic修飾,在類(lèi)加載時(shí)已經(jīng)被初始化,不隨對(duì)象改變而改變。

空白final域

即聲明為final卻沒(méi)有給定初始值的域。

private final String id;//空白final

如果只有上面的這句,編譯器會(huì)報(bào)錯(cuò),因?yàn)樗鼪](méi)有初始化。

Variable 'id' might not have been initialized

所以,若定義了空白final域,一定記得在構(gòu)造器中給它賦值?。ū仨氃谟虻亩x處或者每個(gè)構(gòu)造器中以表達(dá)式對(duì)final進(jìn)行賦值,因?yàn)橄到y(tǒng)不會(huì)為final域默認(rèn)初始化)

//在構(gòu)造器中為空白final域賦初值
public FinalData(){
  id = "空白final默認(rèn)id";
}
public FinalData(String id){
  this.id = id;
}

不要試圖在初始化之前訪問(wèn)域,不然會(huì)報(bào)錯(cuò)。

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

final修飾的參數(shù)

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

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

public int finalParamTest(final int i){
  //!false:i++;
  //不讓改,只讓讀
  return i+1;
}

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

/*檢測(cè)傳入?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無(wú)法傳進(jìn)去,
一定要static修飾?*/

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

public void finalReferenceTest(final FinalData fd){
  //!false:fd = new FinalData();
  //不能再指向新的對(duì)象,存儲(chǔ)地址不準(zhǔn)變
  fd.param0++;
}

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

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

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域在使用前必須被初始化:定義時(shí),構(gòu)造器中*/
public class FinalData {
  /*檢測(cè)傳入?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默認(rèn)id";
  }
  public FinalData(String id){
    this.id = id;
  }
  //帶有編譯時(shí)數(shù)值的final基本類(lèi)型
  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();
    //不能再指向新的對(duì)象,存儲(chǔ)地址不準(zhǔn)變
    fd.param0++;

  }

  public static void main(String[] args) {
    FinalData fd1 = new FinalData("fd1");
    /*基本類(lèi)型變量*/
    //!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 + "]");
    /*引用變量之?dāng)?shù)組*/
    System.out.println("before:fd1.a[] = " + Arrays.toString(fd1.a));

    /*數(shù)組引用變量a是final修飾,
    但是不代表它指向的數(shù)據(jù)值是final,
    而是a存儲(chǔ)的地址值不能改變
     */
    //!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)建了三個(gè)不同的對(duì)象,對(duì)其final 和final static 進(jìn)行測(cè)試
    /*可以發(fā)現(xiàn),三個(gè)對(duì)象的i4值是隨機(jī)生成且不能改變的,且不相同,
    而INT_5的值不隨對(duì)象改變而改變,因?yàn)楸籹tatic修飾,在類(lèi)加載時(shí)已經(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無(wú)法傳進(jìn)去,
    一定要static修飾?*/

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

}

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能

    SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能

    這篇文章主要為大家詳細(xì)介紹了SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • spring?boot項(xiàng)目實(shí)戰(zhàn)之實(shí)現(xiàn)與數(shù)據(jù)庫(kù)的連接

    spring?boot項(xiàng)目實(shí)戰(zhàn)之實(shí)現(xiàn)與數(shù)據(jù)庫(kù)的連接

    在我們?nèi)粘5拈_(kāi)發(fā)過(guò)程中,肯定不可避免的會(huì)使用到數(shù)據(jù)庫(kù)以及SQL?語(yǔ)句,下面這篇文章主要給大家介紹了關(guān)于spring?boot項(xiàng)目實(shí)戰(zhàn)之實(shí)現(xiàn)與數(shù)據(jù)庫(kù)連接的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java線程的相關(guān)方法詳細(xì)解析

    Java線程的相關(guān)方法詳細(xì)解析

    以下是對(duì)Java線程的相關(guān)方法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09
  • Java 基礎(chǔ)--Arrays工具類(lèi)詳解

    Java 基礎(chǔ)--Arrays工具類(lèi)詳解

    這篇文章主要介紹了Java Arrays工具類(lèi)用法,結(jié)合實(shí)例形式分析了java Arrays工具類(lèi)針對(duì)數(shù)組元素修改、復(fù)制、排序等操作使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2021-09-09
  • Java程序員的10道常見(jiàn)的XML面試問(wèn)答題(XML術(shù)語(yǔ)詳解)

    Java程序員的10道常見(jiàn)的XML面試問(wèn)答題(XML術(shù)語(yǔ)詳解)

    包括web開(kāi)發(fā)人員的Java面試在內(nèi)的各種面試中,XML面試題在各種編程工作的面試中很常見(jiàn)。XML是一種成熟的技術(shù),經(jīng)常作為從一個(gè)平臺(tái)到其他平臺(tái)傳輸數(shù)據(jù)的標(biāo)準(zhǔn)
    2014-04-04
  • Mybatis是這樣防止sql注入的

    Mybatis是這樣防止sql注入的

    本文詳細(xì)講解了Mybatis是如何防止sql注入的,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值。需要的朋友可以收藏下,方便下次瀏覽觀看
    2021-12-12
  • spring?boot權(quán)限管理的幾種常見(jiàn)方式

    spring?boot權(quán)限管理的幾種常見(jiàn)方式

    這篇文章主要給大家介紹了關(guān)于spring?boot權(quán)限管理的幾種常見(jiàn)方式,在Web應(yīng)用程序中,用戶(hù)權(quán)限管理是至關(guān)重要的,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • java實(shí)現(xiàn)excel導(dǎo)入數(shù)據(jù)的工具類(lèi)

    java實(shí)現(xiàn)excel導(dǎo)入數(shù)據(jù)的工具類(lèi)

    這篇文章主要介紹了java實(shí)現(xiàn)的excel導(dǎo)入數(shù)據(jù)的工具類(lèi),需要的朋友可以參考下
    2014-03-03
  • Java 比較接口comparable與comparator區(qū)別解析

    Java 比較接口comparable與comparator區(qū)別解析

    這篇文章主要介紹了Java 比較接口comparable與comparator區(qū)別解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java8中List轉(zhuǎn)換String字符串幾種方式

    Java8中List轉(zhuǎn)換String字符串幾種方式

    這篇文章主要給大家介紹了關(guān)于Java8中List轉(zhuǎn)換String字符串的幾種方式,在實(shí)際開(kāi)發(fā)中經(jīng)常遇到List轉(zhuǎn)為String字符串的情況,文中給出了幾種方法的示例代碼,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

临武县| 吴川市| 垣曲县| 临朐县| 伊吾县| 榆林市| 凤凰县| 来安县| 神池县| 长宁县| 黑河市| 石楼县| 平南县| 全南县| 寻甸| 伊宁县| 呼和浩特市| 自治县| 安阳市| 集安市| 林甸县| 舟山市| 石嘴山市| 忻州市| 正蓝旗| 鄱阳县| 云安县| 玛多县| 赤峰市| 侯马市| 黔西县| 祁连县| 博湖县| 本溪市| 新河县| 卓尼县| 乌鲁木齐市| 宜昌市| 龙州县| 虞城县| 荆州市|