程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解Java編程中static症結字和final症結字的應用

詳解Java編程中static症結字和final症結字的應用

編輯:關於JAVA

詳解Java編程中static症結字和final症結字的應用。本站提示廣大學習愛好者:(詳解Java編程中static症結字和final症結字的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Java編程中static症結字和final症結字的應用正文


Java static症結字和Java靜態變量和靜態辦法
static 潤飾符可以或許與變量、辦法一路應用,表現是“靜態”的。

靜態變量和靜態辦法可以或許經由過程類名來拜訪,不須要創立一個類的對象來拜訪該類的靜態成員,所以static潤飾的成員又稱作類變量和類辦法。靜態變量與實例變量分歧,實例變量老是經由過程對象來拜訪,由於它們的值在對象和對象之間有所分歧。

請看上面的例子:

public class Demo {
  static int i = 10;
  int j;
  Demo() {
    this.j = 20;
  }
  public static void main(String[] args) {
    System.out.println("類變量 i=" + Demo.i);
    Demo obj = new Demo();
    System.out.println("實例變量 j=" + obj.j);
  }
}

運轉成果:

類變量 i=10
實例變量 j=20


static 的內存分派

靜態變量屬於類,不屬於任何自力的對象,所以無需創立類的實例便可以拜訪靜態變量。之所以會發生如許的成果,是由於編譯器只為全部類創立了一個靜態變量的正本,也就是只分派一個內存空間,固然有多個實例,但這些實例同享該內存。實例變量則分歧,每創立一個對象,都邑分派一次內存空間,分歧變量的內存互相自力,互不影響,轉變 a 對象的實例變量不會影響 b 對象。

請看上面的代碼:

public class Demo {
  static int i;
  int j;
  public static void main(String[] args) {
    Demo obj1 = new Demo();
    obj1.i = 10;
    obj1.j = 20;
    
    Demo obj2 = new Demo();
    
    System.out.println("obj1.i=" + obj1.i + ", obj1.j=" + obj1.j);
    System.out.println("obj2.i=" + obj2.i + ", obj2.j=" + obj2.j);
  }
}

運轉成果:

obj1.i=10, obj1.j=20
obj2.i=10, obj2.j=0

留意:靜態變量固然也能夠經由過程對象來拜訪,然則不被倡導,編譯器也會發生正告。

下面的代碼中,i 是靜態變量,經由過程 obj1 轉變 i 的值,會影響到 obj2;j 是實例變量,經由過程 obj1 轉變 j 的值,不會影響到 obj2。這是由於 obj1.i 和 obj2.i 指向統一個內存空間,而 obj1.j 和 obj2.j 指向分歧的內存空間,請看下圖:

留意:static 的變量是在類裝載的時刻就會被初始化。也就是說,只需類被裝載,不論你能否應用了這個static 變量,它都邑被初始化。

小結:類變量(class variables)用症結字 static 潤飾,在類加載的時刻,分派類變量的內存,今後再生成類的實例對象時,將同享這塊內存(類變量),任何一個對象對類變量的修正,都邑影響其它對象。內部有兩種拜訪方法:經由過程對象來拜訪或經由過程類名來拜訪。
靜態辦法

靜態辦法是一種不克不及向對象實行操作的辦法。例如,Math 類的 pow() 辦法就是一個靜態辦法,語法為 Math.pow(x, a),用來盤算 x 的 a 次冪,在應用時無需創立任何 Math 對象。

由於靜態辦法不克不及操尴尬刁難象,所以不克不及在靜態辦法中拜訪實例變量,只能拜訪本身類的靜態變量。

以下情況可使用靜態辦法:
一個辦法不須要拜訪對象狀況,其所需參數都是經由過程顯式參數供給(例如 Math.pow())。
一個辦法只須要拜訪類的靜態變量。

讀者確定留意到,main() 也是一個靜態辦法,纰謬任何對象停止操作。現實上,在法式啟動時還沒有任何對象,main() 辦法是法式的進口,將被履行並創立法式所需的對象。

關於靜態變量和靜態辦法的總結:
一個類的靜態辦法只能拜訪靜態變量;
一個類的靜態辦法不克不及夠直接挪用非靜態辦法;
如拜訪掌握權限許可,靜態變量和靜態辦法也能夠經由過程對象來拜訪,然則不被推舉;
靜態辦法中不存在以後對象,因此不克不及應用 this,固然也不克不及應用 super;
靜態辦法不克不及被非靜態辦法籠罩;
結構辦法不許可聲明為 static 的;
部分變量不克不及應用static潤飾。

靜態辦法舉例:

public class Demo {
  static int sum(int x, int y){
    return x + y;
  }
  public static void main(String[] args) {
    int sum = Demo.sum(10, 10);
    System.out.println("10+10=" + sum);
  }
}

運轉成果:

10+10=20

static 辦法不需它所屬的類的任何實例就會被挪用,是以沒有 this 值,不克不及拜訪實例變量,不然會惹起編譯毛病。

留意:實例變量只能經由過程對象來拜訪,不克不及經由過程類拜訪。
靜態初始器(靜態塊)

塊是由年夜括號包抄的一段代碼。靜態初始器(Static Initializer)是一個存在於類中、辦法裡面的靜態塊。靜態初始器僅僅在類裝載的時刻(第一次應用類的時刻)履行一次,常常用來初始化靜態變量。

示例代碼:

public class Demo {
  public static int i;
  static{
    i = 10;
    System.out.println("Now in static block.");
  }
  public void test() {
    System.out.println("test method: i=" + i);
  }
  public static void main(String[] args) {
    System.out.println("Demo.i=" + Demo.i);
    new Demo().test();
  }
}

運轉成果是:

Now in static block.
Demo.i=10
test method: i=10


靜態導入

靜態導入是 Java 5 的新增特征,用來導入類的靜態變量和靜態辦法。

普通我們導入類都如許寫:

import packageName.className; // 導入某個特定的類




import packageName.*; // 導入包中的一切類

而靜態導入可以如許寫:

import static packageName.className.methonName; // 導入某個特定的靜態辦法



import static packageName.className.*; // 導入類中的一切靜態成員

導入後,可以在以後類中直接用辦法名挪用靜態辦法,不用再用 className.methodName 來拜訪。

關於應用頻仍的靜態變量和靜態辦法,可以將其靜態導入。靜態導入的利益是可以簡化一些操作,例如輸入語句 System.out.println(); 中的 out 就是 System 類的靜態變量,可以經由過程 import static java.lang.System.*; 將其導入,下次直接挪用 out.println() 便可以了。

請看上面的代碼:

import static java.lang.System.*;
import static java.lang.Math.random;
public class Demo {
  public static void main(String[] args) {
    out.println("發生的一個隨機數:" + random());
  }
}

運轉成果:

發生的一個隨機數:0.05800891549018705

Java final症結字:阻攔繼續和多態
在 Java 中,聲明類、變量和辦法時,可以使用症結字 final 來潤飾。final 所潤飾的數據具有“終態”的特點,表現“終究的”意思。詳細劃定以下:
final 潤飾的類不克不及被繼續。
final 潤飾的辦法不克不及被子類重寫。
final 潤飾的變量(成員變量或部分變量)即成為常量,只能賦值一次。
final 潤飾的成員變量必需在聲明的同時賦值,假如在聲明的時刻沒有賦值,那末只要 一次賦值的機遇,並且只能在結構辦法中顯式賦值,然後能力應用。
final 潤飾的部分變量可以只聲明不賦值,然後再停止一次性的賦值。

final 普通用於潤飾那些通用性的功效、完成方法或取值不克不及隨便被轉變的數據,以免被誤用,例照實現數學三角辦法、冪運算等功效的辦法,和數學常量π=3.141593、e=2.71828 等。

現實上,為確保終態性,供給了上述辦法和常量的 java.lang.Math 類也已被界說為final 的。

須要留意的是,假如將援用類型(任何類的類型)的變量標志為 final,那末該變量不克不及指向任何其它對象。但可以轉變對象的內容,由於只要援用自己是 final 的。

假如變量被標志為 final,其成果是使它成為常數。想轉變 final 變量的值會招致一個編譯毛病。上面是一個准確界說 final 變量的例子:

public final int MAX_ARRAY_SIZE = 25; // 常量名普通年夜寫


常量由於有 final 潤飾,所以不克不及被繼續。

請看上面的代碼:

public final class Demo{
  public static final int TOTAL_NUMBER = 5;
  public int id;
  public Demo() {
    // 不法,對final變量TOTAL_NUMBER停止二次賦值了
    // 由於++TOTAL_NUMBER相當於 TOTAL_NUMBER=TOTAL_NUMBER+1
    id = ++TOTAL_NUMBER;
  }
  public static void main(String[] args) {
    final Demo t = new Demo();
    final int i = 10;
    final int j;
    j = 20;
    j = 30; // 不法,對final變量停止二次賦值
  }
}

final 也能夠用來潤飾類(放在 class 症結字後面),阻攔該類再派生出子類,例如 Java.lang.String 就是一個 final 類。如許做是出於平安緣由,由於要包管一旦有字符串的援用,就必需是類 String 的字符串,而不是某個其它類的字符串(String 類能夠被歹意繼續並改動)。

辦法也能夠被 final 潤飾,被 final 潤飾的辦法不克不及被籠罩;變量也能夠被 final 潤飾,被 final 潤飾的變量在創立對象今後就不許可轉變它們的值了。一旦將一個類聲明為 final,那末該類包括的辦法也將被隱式地聲明為 final,然則變量不是。

被 final 潤飾的辦法為靜態綁定,不會發生多態(靜態綁定),法式在運轉時不須要再檢索辦法表,可以或許進步代碼的履行效力。在Java中,被 static 或 private 潤飾的辦法會被隱式的聲明為 final,由於靜態綁定沒成心義。

因為靜態綁定會消費資本而且許多時刻沒有需要,所以有一些法式員以為:除非有足夠的來由應用多態性,不然應當將一切的辦法都用 final 潤飾。

如許的熟悉不免難免有些過火,由於 JVM 中的即時編譯器可以或許及時監控法式的運轉信息,可以精確的曉得類之間的繼續關系。假如一個辦法沒有被籠罩而且很短,編譯器就可以夠對它停止優化處置,這個進程為稱為內聯(inlining)。例如,內聯挪用 e.getName() 將被調換為拜訪 e.name 變量。這是一項很成心義的改良,這是因為CPU在處置挪用辦法的指令時,應用的分支轉移會搗亂預取指令的戰略,所以,這被視為不受迎接的。但是,假如 getName() 在別的一個類中被籠罩,那末編譯器就沒法曉得籠罩的代碼將會做甚麼操作,是以也就不克不及對它停止內聯處置了。

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