java中變量和常量詳解
變量和常量
在程序中存在大量的數(shù)據(jù)來(lái)代表程序的狀態(tài),其中有些數(shù)據(jù)在程序的運(yùn)行過(guò)程中值會(huì)發(fā)生改變,有些數(shù)據(jù)在程序運(yùn)行過(guò)程中值不能發(fā)生改變,這些數(shù)據(jù)在程序中分別被叫做變量和常量。
在實(shí)際的程序中,可以根據(jù)數(shù)據(jù)在程序運(yùn)行中是否發(fā)生改變,來(lái)選擇應(yīng)該是使用變量代表還是常量代表。
變量
變量代表程序的狀態(tài)。程序通過(guò)改變變量的值來(lái)改變整個(gè)程序的狀態(tài),或者說(shuō)得更大一些,也就是實(shí)現(xiàn)程序的功能邏輯。
為了方便的引用變量的值,在程序中需要為變量設(shè)定一個(gè)名稱,這就是變量名。例如在2D游戲程序中,需要代表人物的位置,則需要2個(gè)變量,一個(gè)是x坐標(biāo),一個(gè)是y坐標(biāo),在程序運(yùn)行過(guò)程中,這兩個(gè)變量的值會(huì)發(fā)生改變。
由于Java語(yǔ)言是一種強(qiáng)類型的語(yǔ)言,所以變量在使用以前必須首先聲明,在程序中聲明變量的語(yǔ)法格式如下:
數(shù)據(jù)類型變量名稱;
例如:intx;
在該語(yǔ)法格式中,數(shù)據(jù)類型可以是Java語(yǔ)言中任意的類型,包括前面介紹到的基本數(shù)據(jù)類型以及后續(xù)將要介紹的復(fù)合數(shù)據(jù)類型。變量名稱是該變量的標(biāo)識(shí)符,需要符合標(biāo)識(shí)符的命名規(guī)則,在實(shí)際使用中,該名稱一般和變量的用途對(duì)應(yīng),這樣便于程序的閱讀。數(shù)據(jù)類型和變量名稱之間使用空格進(jìn)行間隔,空格的個(gè)數(shù)不限,但是至少需要1個(gè)。語(yǔ)句使用“;”作為結(jié)束。
也可以在聲明變量的同時(shí),設(shè)定該變量的值,語(yǔ)法格式如下:
數(shù)據(jù)類型變量名稱=值;
例如:intx=10;
在該語(yǔ)法格式中,前面的語(yǔ)法和上面介紹的內(nèi)容一致,后續(xù)的“=”代表賦值,其中的“值”代表具體的數(shù)據(jù),注意區(qū)別“==”代表為判斷是否相等。在該語(yǔ)法格式中,要求值的類型需要和聲明變量的數(shù)據(jù)類型一致。
在程序中,變量的值代表程序的狀態(tài),在程序中可以通過(guò)變量名稱來(lái)引用變量中存儲(chǔ)的值,也可以為變量重新賦值。例如:
intn=5;
n=10;
在實(shí)際開(kāi)發(fā)過(guò)程中,需要聲明什么類型的變量,需要聲明多少個(gè)變量,需要為變量賦什么數(shù)值,都根據(jù)程序邏輯決定,這里列舉的只是表達(dá)的格式而已。
常量
常量代表程序運(yùn)行過(guò)程中不能改變的值。
常量在程序運(yùn)行過(guò)程中主要有2個(gè)作用:
1.代表常數(shù),便于程序的修改(例如:圓周率的值)
2.增強(qiáng)程序的可讀性(例如:常量UP、DOWN、LEFT和RIGHT分辨代表上下左右,其數(shù)值分別是1、2、3和4)
常量的語(yǔ)法格式和變量類型,只需要在變量的語(yǔ)法格式前面添加關(guān)鍵字final即可。在Java編碼規(guī)范中,要求常量名必須大寫(xiě)。
則常量的語(yǔ)法格式如下:
final數(shù)據(jù)類型常量名稱=值;
final數(shù)據(jù)類型常量名稱1=值1,常量名稱2=值2,……常量名稱n=值n;
例如:
finaldoublePI=3.14;
finalcharMALE=‘M',F(xiàn)EMALE=‘F';
在Java語(yǔ)法中,常量也可以首先聲明,然后再進(jìn)行賦值,但是只能賦值一次,示例代碼如下:
finalintUP;
UP=1;
關(guān)于final詳解
final用于聲明屬性(常量),方法和類,分別表示屬性一旦被分配內(nèi)存空間就必須初始化(不會(huì)有默認(rèn)初始化,局部變量也是如此,默認(rèn)初始化只有普通的非final成員屬性,對(duì)于static(無(wú)final修飾)類變量,類連接時(shí)候有默認(rèn)初始化,對(duì)于像privateinta;在類實(shí)例化時(shí),構(gòu)造函數(shù)默認(rèn)初始為0,總之,變量必須初始化后方可用,這是java的安全之一。final這個(gè)關(guān)鍵字的含義是“這是無(wú)法改變的”或者“終態(tài)的”;
那么為什么要阻止改變呢?
java語(yǔ)言的發(fā)明者可能由于兩個(gè)目的而阻止改變:
1).效率問(wèn)題:
jdk中的某些類的某些方法,是不允許被用戶覆蓋的,設(shè)計(jì)者可能認(rèn)為,所用方法已經(jīng)是最好的方法,用戶私自覆蓋,或是由于疏忽而覆蓋,就會(huì)影響JVM或是系統(tǒng)的系能;
2).設(shè)計(jì)所需:
眾所周知,有些情況必須使用final關(guān)鍵字,比如方法中的匿名內(nèi)部類的參數(shù)傳遞
【修飾變量】:
final成員變量表示常量,只能被賦值一次,賦值后值不再改變。
【修飾方法】:
final方法不能被子類方法覆蓋,但可以被繼承。
【修飾類】:
final類不能被繼承,沒(méi)有子類,final類中所有方法都是final的。(如String類)
1.被final修飾而沒(méi)有被static修飾的類的屬性變量只能在兩種情況下初始化:(必須初始化)
a.在它被聲明的時(shí)候賦值
b.在構(gòu)造函數(shù)里初始化
解釋:當(dāng)這個(gè)屬性被修飾為final,而非static的時(shí)候,它屬于類的實(shí)例對(duì)象的資源(實(shí)例常量),當(dāng)類被加載進(jìn)內(nèi)存的時(shí)候這個(gè)屬性并沒(méi)有給其分配內(nèi)存空間,而只是定義了一個(gè)變量a,只有當(dāng)類被實(shí)例化的時(shí)候這個(gè)屬性才被分配內(nèi)存空間,而實(shí)例化的時(shí)候同時(shí)執(zhí)行了構(gòu)造函數(shù),所以屬性被初始化了,也就符合了當(dāng)它被分配內(nèi)存空間的時(shí)候就需要初始化,以后不再改變的條件.
2.被static修飾而沒(méi)有被final修飾的類的屬性變量只能在兩種情況下初始化:(可以不初始化)
a.在它被聲明的時(shí)候賦值
b.在靜態(tài)或非靜態(tài)快里初始化
解釋:
當(dāng)類的屬性被同時(shí)被修飾為static時(shí)候,他屬于類的資源(類變量),在類加載后,進(jìn)行連接時(shí)候,分三步:先驗(yàn)證;然后準(zhǔn)備,準(zhǔn)備時(shí),先分配內(nèi)存,接著默認(rèn)初始化;可以進(jìn)行解析。最后,進(jìn)行類初始化,類初始化前,必須保證它的父類已經(jīng)初始化了,所以最先初始化的是超類,對(duì)于接口,不必初始其父接口。類初始化時(shí),它把類變量初始化語(yǔ)句及靜態(tài)初始化語(yǔ)句放到類初始化方法中,所以,如果無(wú)此兩種語(yǔ)句,也就沒(méi)<clinit>類初始化方法,而構(gòu)造函數(shù)是在當(dāng)類被實(shí)例化的時(shí)候才會(huì)執(zhí)行,所以用構(gòu)造函數(shù),這時(shí)候這個(gè)屬性沒(méi)有被初始化.程序就會(huì)報(bào)錯(cuò).而static塊是類被加載的時(shí)候執(zhí)行,且只執(zhí)行這一次,所以在static塊中可以被初始化.
3.同時(shí)被final和static修飾的類的屬性變量只能在兩種情況下初始化:(必須初始化)
a.在它被定義的時(shí)候
b.在類的靜態(tài)塊里初始化
c.特別對(duì)于初始化時(shí)候調(diào)用拋出異常的構(gòu)造函數(shù),初始時(shí)候注意,特別是在實(shí)現(xiàn)單例模式時(shí)(只能這么初始化)
如:
class A { private final static A a; static { try { a=new A(); } catch(Exception e) { throws new RuntimeException(e); //必須有,不然不能完成常量的正確初始化 } } private A() throws Exception{ } }
解釋:
當(dāng)類的屬性被同時(shí)被修飾為static和final的時(shí)候,他屬于類的資源(類常量),那么就是類在被加載進(jìn)內(nèi)存的時(shí)候(也就是應(yīng)用程序啟動(dòng)的時(shí)候)就要已經(jīng)為此屬性分配了內(nèi)存,所以此時(shí)屬性已經(jīng)存在,它又被final修飾,所以必須在屬性定義了以后就給其初始化值.而構(gòu)造函數(shù)是在當(dāng)類被實(shí)例化的時(shí)候才會(huì)執(zhí)行,所以用構(gòu)造函數(shù),這時(shí)候這個(gè)屬性沒(méi)有被初始化.程序就會(huì)報(bào)錯(cuò).而static塊是類被加載的時(shí)候執(zhí)行,且只執(zhí)行這一次,所以在static塊中可以被初始化.
java中的final變量==常量
【final變量的變與不變】:final表示變量的值或引用不變
有人說(shuō)final變量在賦值后就不可變,此變量可以是基本數(shù)據(jù)類型+String或者是對(duì)象
那么這個(gè)不變到底指的是什么呢?
這個(gè)不變指的是引用,是地址,而所引用的對(duì)象的內(nèi)容仍然是可變的。注:如果為對(duì)象,注意此時(shí)類初始化條件
就是說(shuō),這個(gè)final變量永遠(yuǎn)指向某個(gè)對(duì)象,是一個(gè)常量指針,而不是指向常量的指針。
【final關(guān)鍵字的具體應(yīng)用】:
【final+變量】:
在實(shí)際應(yīng)用中,這種形式是非常少見(jiàn)的。
比如logger是可以的,但是貌似并不是非常實(shí)用,或許用戶仍然希望通過(guò)setter來(lái)改變logger變量。
【static+final+變量】:
常量。經(jīng)常使用。
【final+方法】:
JDK中常用,但是自己并未常用。
【final+類】:
helper類經(jīng)常使用。
【final用于匿名內(nèi)部類的參數(shù)傳遞】:
在多線程測(cè)試時(shí),經(jīng)常使用。
【final用于方法的參數(shù)】:
并不常用。
延伸:
在interface里面的變量都是publicstaticfinal的。所以你可以這樣寫(xiě):
publicstaticfinalinti=10;
或則
inti=10;(可以省略掉一部分)
注意在聲明的時(shí)候要給變量賦予初值
解釋:
首先你要弄清接口的含義.接口就是提供一種統(tǒng)一的'協(xié)議',而接口中的屬性也屬于'協(xié)議'中的成員.它們是公共的,靜態(tài)的,最終的常量.相當(dāng)于全局常量.
抽象類是不'完全'的類,相當(dāng)于是接口和具體類的一個(gè)中間層.即滿足接口的抽象,也滿足具體的實(shí)現(xiàn).
如果接口可以定義變量,但是接口中的方法又都是抽象的,在接口中無(wú)法通過(guò)行為來(lái)修改屬性。有的人會(huì)說(shuō)了,沒(méi)有關(guān)系,可以通過(guò)實(shí)現(xiàn)接口的對(duì)象的行為來(lái)修改接口中的屬性。這當(dāng)然沒(méi)有問(wèn)題,但是考慮這樣的情況。如果接口A中有一個(gè)public訪問(wèn)權(quán)限的靜態(tài)變量a。按照java的語(yǔ)義,我們可以不通過(guò)實(shí)現(xiàn)接口的對(duì)象來(lái)訪問(wèn)變量a,通過(guò)A.a=xxx;就可以改變接口中的變量a的值了。正如抽象類中是可以這樣做的,那么實(shí)現(xiàn)接口A的所有對(duì)象也都會(huì)自動(dòng)擁有這一改變后的a的值了,也就是說(shuō)一個(gè)地方改變了a,所有這些對(duì)象中a的值也都跟著變了。如果可以修改值:這和抽象類有什么區(qū)別呢,怎么體現(xiàn)接口更高的抽象級(jí)別呢,怎么體現(xiàn)接口提供的統(tǒng)一的協(xié)議呢,那還要接口這種抽象來(lái)做什么呢?所以接口中不能出現(xiàn)變量,如果有變量,就和接口提供的統(tǒng)一的抽象這種思想是抵觸的。所以接口中的屬性必然是常量,只能讀不能改,這樣才能為實(shí)現(xiàn)接口的對(duì)象提供一個(gè)統(tǒng)一的屬性。
通俗的講,你認(rèn)為是要變化的東西,就放在你自己的實(shí)現(xiàn)中,不能放在接口中去,接口只是對(duì)一類事物的屬性和行為更高層次的抽象。對(duì)修改關(guān)閉,對(duì)擴(kuò)展(不同的實(shí)現(xiàn)implements)開(kāi)放,接口是對(duì)開(kāi)閉原則的一種體現(xiàn)。
總結(jié)
以上就是本文關(guān)于Java中變量和常量詳解的全部?jī)?nèi)容,希望對(duì)打擊有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Java并發(fā)編程Semaphore計(jì)數(shù)信號(hào)量詳解、詳解java中的互斥鎖信號(hào)量和多線程等待機(jī)制、淺談java中的局部變量和全局變量等,歡迎大家提出寶貴意見(jiàn),小編一定及時(shí)回復(fù)。感謝朋友們對(duì)本站的支持!
相關(guān)文章
解決SpringBoot項(xiàng)目在啟動(dòng)后自動(dòng)關(guān)閉的問(wèn)題
今天搭建了一個(gè)SpringBoot項(xiàng)目,但是在啟動(dòng)之后就自行關(guān)閉了,下面通過(guò)本文給大家介紹SpringBoot項(xiàng)目在啟動(dòng)后自動(dòng)關(guān)閉問(wèn)題及解決方法,需要的朋友可以參考下2023-08-08在CentOS系統(tǒng)中檢測(cè)Java安裝及運(yùn)行jar應(yīng)用的方法
這篇文章主要介紹了在CentOS系統(tǒng)中檢測(cè)Java安裝及運(yùn)行jar應(yīng)用的方法,同樣適用于Fedora等其他RedHat系的Linux系統(tǒng),需要的朋友可以參考下2015-06-06Java將中文轉(zhuǎn)化為拼音的簡(jiǎn)單代碼示例
在我們使用手機(jī)通訊錄或各種APP的搜索功能時(shí),既可以根據(jù)中文搜索,也可以根據(jù)拼音搜索,這種時(shí)候就使用到了中文轉(zhuǎn)拼音的功能了,下面這篇文章主要給大家介紹了關(guān)于Java將中文轉(zhuǎn)化為拼音的簡(jiǎn)單代碼示例,需要的朋友可以參考下2024-03-03Mybatis注解開(kāi)發(fā)單表、多表操作的實(shí)現(xiàn)代碼
這篇文章主要介紹了Mybatis高級(jí):Mybatis注解開(kāi)發(fā)單表操作,Mybatis注解開(kāi)發(fā)多表操作,構(gòu)建sql語(yǔ)句,綜合案例學(xué)生管理系統(tǒng)使用接口注解方式優(yōu)化,需要的朋友可以參考下2021-02-02盤(pán)點(diǎn)Java中延時(shí)任務(wù)的多種實(shí)現(xiàn)方式
當(dāng)需要一個(gè)定時(shí)發(fā)布系統(tǒng)通告的功能,如何實(shí)現(xiàn)??當(dāng)支付超時(shí),訂單自動(dòng)取消,如何實(shí)現(xiàn)?其實(shí)這些問(wèn)題本質(zhì)都是延時(shí)任務(wù)的實(shí)現(xiàn),本文為大家盤(pán)點(diǎn)了多種常見(jiàn)的延時(shí)任務(wù)實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2022-12-12SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn)
Prometheus作為一個(gè)開(kāi)源的監(jiān)控和告警工具,以其強(qiáng)大的數(shù)據(jù)采集、存儲(chǔ)和查詢能力,受到了眾多開(kāi)發(fā)者的青睞,本文主要介紹了SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn),感興趣的可以了解一下2024-07-07Java通過(guò)MySQL的加解密函數(shù)實(shí)現(xiàn)敏感字段存儲(chǔ)
這篇文章主要介紹了如何在Java中MySQL的加解密函數(shù)實(shí)現(xiàn)敏感字段存儲(chǔ),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-03-03SpringCloudConfig之client端報(bào)錯(cuò)Could?not?resolve?placeholder問(wèn)
這篇文章主要介紹了SpringCloudConfig之client端報(bào)錯(cuò)Could?not?resolve?placeholder?‘from‘?in?value?“${from}“問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2022-12-12Java?AQS?線程安全同步隊(duì)列的實(shí)現(xiàn)
AQS 同步隊(duì)列是很多的 Java 線程安全對(duì)象的實(shí)現(xiàn),例如 ReentrantLock, Semaphore, CountDownLatch, ReentrantReadWriteLock 等等,本文就介紹了Java?AQS?線程安全同步隊(duì)列的實(shí)現(xiàn),感興趣的可以了解一下2023-08-08