您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Java中static的作用是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
為什么需要static?
有時候我們并不想去new一個對象,只是單純的想要調用一個函數,并且希望這個函數不會與包含它的類的其他對象有所關聯。說得通俗點,即使沒有創建對象,也能通過類本身來調用函數。
static靜態變量
被static修飾的變量屬于類變量,通過字面意思就說明了這個變量的歸屬(類),與之相對的是沒有被static修飾的成員變量,也稱為實例變量,說明這個變量是屬于某個具體的對象。
public class StaticDemo { private static int i = 50; private int j = 60; public static void main(String[] args) { StaticDemo staticDemo = new StaticDemo(); StaticDemo staticDemo1 = new StaticDemo(); //即使創建兩個對象,也都指向同一存儲空間 System.out.println(staticDemo.i); System.out.println(staticDemo1.i); //改變值 staticDemo.i = 52; System.out.println(staticDemo1.i); staticDemo.j = 65; staticDemo1.j = 70; System.out.println(staticDemo.j); System.out.println(staticDemo1.j); } }
輸出
50
50
52
65
70
通過上面的實例,我們很快看出他們的區別
靜態變量是屬于類的,只有一份存儲空間,是類之間共享的,牽一發而動全身,一處變,處處變。
實例變量屬于實例對象,創建幾次對象,就有幾份的成員變量(拷貝)。
static修飾的靜態函數
說到靜態函數,就不得不提Java另一個關鍵詞this,指的是當前的引用。意思是調用這個函數的對象,這意味著和static修飾的函數水火不容。被static修飾的函數,不能出現this關鍵字,否則便會報錯。
去掉this,分別調用i或者j,會發現靜態函數調用非靜態資源時出錯。這是為什么?從JVM加載機制角度來說,靜態資源(被staitc修飾)是類在初始化的時候就加載的,而非靜態資源是new的時候加載的。類的初始化是早于new的,加載了say()的函數時,它并不認識 j 這個成員變量,但對于非靜態函數來說,當它加載時,靜態資源已經加載完畢,所以它是認識 i 這個靜態資源的。我們總結一下static修飾函數時的特點
靜態函數不能引用非靜態資源;
非靜態函數可以引用靜態資源;
靜態函數可以相互調用(只要引入所在包即可);
靜態函數沒有this,因為它不依附于任何對象。
現在,我們也能知道main函數為什么必須是static的,因為程序在執行main函數時候,沒有創建任何對象,只是通過類名來訪問。
構造函數是不是靜態函數?
《Java編程思想》提到“即使沒有顯示地使用static關鍵字,構造器實際上也是靜態方法”。我至今不能確認構造器是不是靜態函數,個人更偏向于不是。原因待會再闡述,先看個實例
public class StaticTest { private static int i; private int j; public StaticTest(int i,int j){ this.i = i; this.j = j; say1() } public void say1() { System.out.println("you age is" + i); System.out.println("you age is" + j); } public static void main(String[] args) { StaticTest staticTest = new StaticTest(4,5); StaticTest staticTest1 = new StaticTest(10,69); System.out.println(staticTest.i); System.out.println(staticTest.j); System.out.println(staticTest1.i); System.out.println(staticTest1.j); } }
輸出
you age is4
you age is5
you age is10
you age is69
10
5
10
69
實例中,確實改變了 i 的值,也符合靜態資源的定義,只有一份存儲空間。但構造器里用了this,與我前文所說的static屬于類,不屬于任何對象,this屬于當前引用對象互相矛盾,并且構造函數還可以調用實例函數。一臉懵逼,這也是讓我感到困惑并且認為構造函數不是靜態函數的地方。如有周知,留言解惑,感謝。
靜態塊與非靜態塊
private static int i;
static
{
i = 5;
}
靜態塊是static的重要應用之一,無函數名、作用域、返回值以及參數,靜態代碼塊與靜態變量和靜態函數一樣,不論類被調用多少次,該區域代碼只在類初始化時第一次時執行一次,并且嚴格按照靜態資源的定義順序執行加載,與靜態函數區別在于一個主動一個被動。
{
System.out.println("我是靜態塊.");
}
非靜態塊,同樣無函數名,作用域,返回值以及參數,非靜態代碼塊會在每次類被調用或者被實例化時執行。
實例
public class StaticTest extends Father { public StaticTest() { System.out.println("我是StaticTest的構造函數"); } { System.out.println("我是StaticTest的非靜態塊"); } static { System.out.println("我是StaticTest的靜態塊"); } public static void main(String[] args) { new StaticTest(); new StaticTest(); } } class Father { public Father() { System.out.println("我是Father構造函數"); } { System.out.println("我是Father非靜態塊1"); } { System.out.println("我是Father非靜態塊2"); } static { System.out.println("我是Father靜態塊"); } }
輸出
我是Father靜態塊
我是StaticTest的靜態塊
我是Father非靜態塊1
我是Father非靜態塊2
我是Father構造函數
我是StaticTest的非靜態塊
我是StaticTest的構造函數
我是Father非靜態塊1
我是Father非靜態塊2
我是Father構造函數
我是StaticTest的非靜態塊
我是StaticTest的構造函數
加載順序 :父類靜態塊 > 子類靜態塊 > 父類非靜態塊 > 父類構造函數 > 子類非靜態塊 > 子類構造函數
靜態代碼塊以及非靜態代碼塊都會在構造函數前執行,首次訪問時,靜態代碼塊會在非靜態代碼塊前執行。
改變main函數
public static void main(String[] args)
{
}
輸出
我是Father靜態塊
我是StaticTest的靜態塊
靜態代碼塊在類加載時自動執行,非靜態代碼塊是在創建對象時自動執行的代碼,不創建對象不執行該類的非靜態代碼塊。
靜態導入
靜態導入是jdk5引入的新特性,有時我們在實際應用中,并不需要整個jar包都導入,而只是想使用某部分函數。提高代碼的閱讀性,更好的理解程序。
import static java.lang.System.out; public class StaticTest { public static void main(String[] args) { out.println("import static測試"); System.out.println("import static測試"); } }
輸出
import static測試
import static測試
以上就是Java中static的作用是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。