程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java 變量和常量

Java 變量和常量

編輯:JAVA編程入門知識

變量和常量

    在程序中存在大量的數據來代表程序的狀態,其中有些數據在程序的運行過程中值會發生改變,有些數據在程序運行過程中值不能發生改變,這些數據在程序中分別被叫做變量和常量。

    在實際的程序中,可以根據數據在程序運行中是否發生改變,來選擇應該是使用變量代表還是常量代表。


變量

    變量代表程序的狀態。程序通過改變變量的值來改變整個程序的狀態,或者說得更大一些,也就是實現程序的功能邏輯。
    為了方便的引用變量的值,在程序中需要為變量設定一個名稱,這就是變量名。例如在2D游戲程序中,需要代表人物的位置,則需要2個變量,一個是x坐標,一個是y坐標,在程序運行過程中,這兩個變量的值會發生改變。
    由於Java語言是一種強類型的語言,所以變量在使用以前必須首先聲明,在程序中聲明變量的語法格式如下:
    數據類型 變量名稱;
    例如:int x;
    在該語法格式中,數據類型可以是Java語言中任意的類型,包括前面介紹到的基本數據類型以及後續將要介紹的復合數據類型。變量名稱是該變量的標識符,需要符合標識符的命名規則,在實際使用中,該名稱一般和變量的用途對應,這樣便於程序的閱讀。數據類型和變量名稱之間使用空格進行間隔,空格的個數不限,但是至少需要1個。語句使用“;”作為結束。
    也可以在聲明變量的同時,設定該變量的值,語法格式如下:
    數據類型 變量名稱 = 值;
    例如:int x = 10;
    在該語法格式中,前面的語法和上面介紹的內容一致,後續的“=”代表賦值,其中的“值”代表具體的數據,注意區別“==”代表為判斷是否相等。在該語法格式中,要求值的類型需要和聲明變量的數據類型一致。
       在程序中,變量的值代表程序的狀態,在程序中可以通過變量名稱來引用變量中存儲的值,也可以為變量重新賦值。例如:
    int n = 5;
    n = 10;
    在實際開發過程中,需要聲明什麼類型的變量,需要聲明多少個變量,需要為變量賦什麼數值,都根據程序邏輯決定,這裡列舉的只是表達的格式而已。


    常量

    常量代表程序運行過程中不能改變的值。
    常量在程序運行過程中主要有2個作用:
         1. 代表常數,便於程序的修改(例如:圓周率的值)
         2. 增強程序的可讀性(例如:常量UP、DOWN、LEFT和RIGHT分辨代表上下左右,其數值分別是1、2、3和4)
    常量的語法格式和變量類型,只需要在變量的語法格式前面添加關鍵字final即可。在Java編碼規范中,要求常量名必須大寫。
    則常量的語法格式如下:
    final 數據類型 常量名稱 = 值;
    final 數據類型 常量名稱1 = 值1, 常量名稱2 = 值2,……常量名稱n = 值n;
    例如:
    final double PI = 3.14;
    final char MALE=‘M’,FEMALE=‘F’;
    在Java語法中,常量也可以首先聲明,然後再進行賦值,但是只能賦值一次,示例代碼如下:
 final int UP;
    UP = 1;

 

關於final詳解
     final 用於聲明屬性(常量),方法和類,分別表示屬性一旦被分配內存空間就必須初始化(不會有默認初始化,局部變量也是如此,默認初始化只有普通的非final成員屬性,對於static(無final修飾)類變量,類連接時候有默認初始化,對於像private int a;在類實例化時,構造函數默認初始為0,總之,變量必須初始化後方可用,這是java的安全之一。                    final這個關鍵字的含義是“這是無法改變的”或者“終態的”;
    那麼為什麼要阻止改變呢?
    java語言的發明者可能由於兩個目的而阻止改變:
    1).效率問題:
    jdk中的某些類的某些方法,是不允許被用戶覆蓋的,設計者可能認為,所用方法已經是最好的方法,用戶私自覆蓋,或是由於疏忽而覆蓋,就會影響JVM或是系統的系能;
    2). 設計所需:
    眾所周知,有些情況必須使用final關鍵字,比如方法中的匿名內部類的參數傳遞

    【修飾變量】:
     final成員變量表示常量,只能被賦值一次,賦值後值不再改變。
    【修飾方法】:
     final方法不能被子類方法覆蓋,但可以被繼承。
    【修飾類】:
     final類不能被繼承,沒有子類,final類中所有方法都是final的。(如String類)


1.被final修飾而沒有被static修飾的類的屬性變量只能在兩種情況下初始化:(必須初始化)
a.在它被聲明的時候賦值 
b.在構造函數裡初始化
解釋:                                                                                                                                                                                     當這個屬性被修飾為final,而非static的時候,它屬於類的實例對象的資源(實例常量),當類被加載進內存的時候這個屬性並沒有給其分配內存空間,而只是 定義了一個變量a,只有當類被實例化的時候這個屬性才被分配內存空間,而實例化的時候同時執行了構造函數,所以屬性被初始化了,也就符合了當它被分配內存 空間的時候就需要初始化,以後不再改變的條件.

2.被static修飾而沒有被final修飾的類的屬性變量只能在兩種情況下初始化:(可以不初始化)
a.在它被聲明的時候賦值
b.在靜態或非靜態快裡初始化
解釋:
當類的屬性被同時被修飾為static時候,他屬於類的資源(類變量),在類加載後,進行連接時候,分三步: 先驗證;然後准備,准備時,先分配內存,接著默認初始化;可以進行解析。最後,進行類初始化,類初始化前,必須保證它的父類已經初始化了,所以最先初始化的是超類,對於接口,不必初始其父接口。類初始化時,它把類變量初始化語句及靜態初始化語句放到類初始化方法中,所以,如果無此兩種語句,也就沒<clinit>類初始化方法,而構造函數是在當類 被實例化的時候才會執行,所以用構造函數,這時候這個屬性沒有被初始化.程序就會報錯.而static塊是類被加載的時候執行,且只執行這一次,所以在 static塊中可以被初始化.

3.同時被final和static修飾的類的屬性變量只能在兩種情況下初始化:(必須初始化)
a.在它被定義的時候
b.在類的靜態塊裡初始化 
c.特別對於初始化時候調用拋出異常的構造函數,初始時候注意,特別是在實現單例模式時(只能這麼初始化)
如:
class A

private final static A a;
static
{
try
{
a=new A();
}catch(Exception e)
{
throws new RuntimeException(e);          //必須有,不然不能完成常量的正確初始化
}
}
private A() throws Exception{}
}
解釋:
當類的屬性被同時被修飾為static和final的時候,他屬於類的資源(類常量),那麼就是類在被加載進內存的時候(也就是應用程 序啟動的時候)就要已經為此屬性分配了內存,所以此時屬性已經存在,它又被final修飾,所以必須在屬性定義了以後就給其初始化值.而構造函數是在當類 被實例化的時候才會執行,所以用構造函數,這時候這個屬性沒有被初始化.程序就會報錯.而static塊是類被加載的時候執行,且只執行這一次,所以在 static塊中可以被初始化.

 

 java中的 final變量==常量

【final變量的變與不變】:final表示變量的值或引用不變
    有人說final變量在賦值後就不可變,此變量可以是基本數據類型+String或者是對象
    那麼這個不變到底指的是什麼呢?
    這個不變指的是引用,是地址,而所引用的對象的內容仍然是可變的。注:如果為對象,注意此時類初始化條件
    就是說,這個final變量永遠指向某個對象,是一個常量指針,而不是指向常量的指針。

【final關鍵字的具體應用】:
    【final+變量】:
        在實際應用中,這種形式是非常少見的。
        比如logger是可以的,但是貌似並不是非常實用,或許用戶仍然希望通過setter來改變logger變量。
    【static+final+變量】:
        常量。經常使用。
    【final+方法】:
        JDK中常用,但是自己並未常用。
    【final+類】:
        helper類經常使用。
    【final用於匿名內部類的參數傳遞】:
        在多線程測試時,經常使用。
    【final用於方法的參數】:
        並不常用。   

 

延伸:

在interface裡面的變量都是public static final 的。所以你可以這樣寫:
public static final int i=10;
或則
int i=10;(可以省略掉一部分)
注意在聲明的時候要給變量賦予初值

解釋:
       首先你要弄清接口的含義.接口就是提供一種統一的’協議’,而接口中的屬性也屬於’協議’中的成員.它們是公共的,靜態的,最終的常量.相當於全局常量.
       抽象類是不’完全’的類,相當於是接口和具體類的一個中間層.即滿足接口的抽象,也滿足具體的實現.
       如果接口可以定義變量,但是接口中的方法又都是抽象的,在接口中無法通過行為來修改屬性。有的人會說了,沒有關系,可以通過實現接口的對象的行為來修改接口中的屬性。這當然沒有問題,但是考慮這樣的情況。如果接口A中有一個public訪問權限的靜態變量a。按照java的語義,我們可以不通過實現接口的對象來訪問變量a,通過A.a = xxx;就可以改變接口中的變量a的值了。正如抽象類中是可以這樣做的,那麼實現接口A的所有對象也都會自動擁有這一改變後的a的值了,也就是說一個地方改變了a,所有這些對象中a的值也都跟著變了。如果可以修改值:這和抽象類有什麼區別呢,怎麼體現接口更高的抽象級別呢,怎麼體現接口提供的統一的協議呢,那還要接口這種抽象來做什麼呢?所以接口中不能出現變量,如果有變量,就和接口提供的統一的抽象這種思想是抵觸的。所以接口中的屬性必然是常量,只能讀不能改,這樣才能為實現接口的對象提供一個統一的屬性。
       通俗的講,你認為是要變化的東西,就放在你自己的實現中,不能放在接口中去,接口只是對一類事物的屬性和行為更高層次的抽象。對修改關閉,對擴展(不同的實現implements)開放,接口是對開閉原則的一種體現。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved