一篇文章全方位了解:static main final
文章目錄
- 1. 前言
- 2. 簡介JVM內存模型的虛擬機棧,堆和方法區
- 3.static
- 2.1 為什么需要static?
- 2.2 static修飾的屬性、方法、代碼塊、內部類的特點
- 2.2 static 屬性
- 2.3 static 方法
- 2.4 static的屬性和方法在父類與子類之間的繼承和重寫關系
- 2.5 static代碼塊與非static代碼塊
- 2.6 程序中成員變量賦值的執行順序
- 2.7 靜態內部類
- 4.static與main
- 4.1 static與main方法簡介
- 4.2 面試題
- 5.final
- 5.1 final 修飾變量—— 常量
- 5.2 final修飾類
- 5.3 final修飾方法
- 5.4 static final---全局常量
- 5.5 面試題
本篇文章已同步到:https://www.bithachi.cn/posts/725e9ca.html
1. 前言
- 本篇文章主要介紹Java語言中的兩大關鍵字satic和final,還有main方法與static的淵源。
- static的中文意思是靜態的,final的中文意思是最終的,不可更改的。
我們將從以下三大主線講解:
2. 簡介JVM內存模型的虛擬機棧,堆和方法區
這里只介紹虛擬機棧,堆和方法區,因為這篇文章需要使用到。
-
通常所說的棧(Stack) ,是指虛擬機棧。虛擬機棧用于存儲局部變量等。局部變量表存放了編譯期可知長度的各種基本數據類型(boolean、byte、char、short、int、float、long、double ),對象引用( reference類型,它不等同于對象本身,是對象在堆內存的首地址)。方法執行完, 自動釋放,從棧中彈出。
-
堆(Heap),此內存區域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內存。這一點在Java虛擬機規范中的描述是:所有的對象實例以及數組都要在堆上分配。
-
方法區(Method Area),用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。
3.static
2.1 為什么需要static?
- 有時候我們想要讓所有同一個類的實例對象共享同一個數據,那么我們就需要用到類變量,也就是static修飾的變量。
- 這個數據可以是屬性、方法、代碼塊、內部類
2.2 static修飾的屬性、方法、代碼塊、內部類的特點
2.2 static 屬性
- static修飾的類變量(類屬性)由該類的所有實例共享
- static修飾的屬性可以被繼承
- 當某一個實例改變了static修飾的屬性的值時,其它實例變量使用時是修改后的值,如下圖所舉例子所示:
2.3 static 方法
-
static修飾的方法簡稱類方法
-
沒有對象的實例時,可以用 類名. 方法名()的形式訪問由static修飾的類方法。
-
在static 方法內部只能訪問類的static 修飾的屬性或方法, 不能訪問類的非static 的結構。
-
因為不需要實例就可以訪問static 方法,因此static 方法內部不能有this 。當然也不能有super
-
static修飾的方法不可以重寫,重寫的定義是:方法名、返回值類型、參數列表 與父類中某個方法一樣。經檢驗子類必須寫的和父類一模一樣加static才可以覆蓋static方法,而這不滿足重寫的定義,所以不能叫重寫
-
static修飾的屬性和方法可以繼承,可以使用子類類名訪問,但是不能通過子類對象訪問。
2.4 static的屬性和方法在父類與子類之間的繼承和重寫關系
下面一個例子測試了static的屬性和方法在父類與子類之間的繼承和重寫關系:
public class Person {public static String s="Person";//測試重寫public static void display() {//測試重寫System.out.println("Person display");}public static String ss="Person two"; //測試繼承性public static void displayPerson() {測試繼承性System.out.println("Person displayPerson");} } public class Man extends Person {public static String s="Man";public static void display() {//將static去掉報錯System.out.println("Man display");}private static int total = 0;private int id=0;public Man() {total++;}public static int getTotalPerson() {//id++; //靜態方法不能訪問非靜態屬性和方法//displayA();//this.total=10;//this.id=10;return total;}} public class TestMain {public static void main(String[] args) {/************ 打印Person的屬性和方法做對比 ************/System.out.println(Person.s);System.out.println(Person.ss);Person.display();Person.displayPerson();System.out.println("---------");/************ 測試繼承性 ************/System.out.println(Man.ss);Man.displayPerson();System.out.println("---------");/************ 測試重寫性 ************/System.out.println(Man.s);Man.display();/************ 測試多態性 ************/Person p=new Man();//不能調用Person和Man的任何屬性方法,只能調用Object的屬性和方法Man mm=new Man();//mm不能訪問Person的static屬性和static方法System.out.println("---------");System.out.println("total is " + Man.getTotalPerson());Man p1 = new Man();//執行構造器total+1System.out.println("total is " + Man.getTotalPerson());} }運行結果:
Person Person two Person display Person displayPerson --------- Person two Person displayPerson --------- Man Man display --------- total is 1 total is 22.5 static代碼塊與非static代碼塊
既然已經說到了代碼塊,那么就一次性把靜態和非靜態代碼塊一次性盡量總結完叭
- 代碼塊(或初始化塊)的作用:
對Java 類或對象進行初始化 - 代碼塊(或初始化塊)的分類:
一個類中代碼塊若有修飾符,則只能被static修飾,稱為靜態代碼塊(static block),沒有使用static修飾的,為非靜態代碼塊 。 - static 代碼塊化 通常用于初始化static
靜態代碼塊:用static 修飾的代碼塊
非靜態代碼塊:沒有static 修飾的代碼塊
- 靜態代碼塊不可以繼承,只隨類的加載執行一次
- 非靜態代碼塊可繼承,每次創建對象的時候,都會執行一次。且先于構造器執行
下面看個例子:
public class Person {Person(){System.out.println("person construct");}public int a=1,b=1;{//`每次創建對象的時候,都會執行一次。且先于構造器執行`a++;int x=20;int b=2;{ // int b=2;//不能在嵌套的兩個{{}}定義相同的變量a++;}a++;System.out.println("no static Person a="+a);}public static int c=1,d=1;static{//`靜態代碼塊隨著類的加載而加載,且只執行一次`c++;int b=2;int yy=20;{ // int b=2;//不能在嵌套的兩個{{}}定義相同的變量c++;}c++;System.out.println("static Person c="+c);}} public class Man extends Person {Man(){this.a=10;//不能this.c this.dthis.b=10;System.out.println("Man a="+a);System.out.println("Man b="+b);}} public class TestMain {public static void main(String[] args) {Person p=new Person();System.out.println("-----------");Man m=new Man();System.out.println("---------");System.out.println(Man.c);System.out.println(Man.d);System.out.println(m.a);System.out.println(m.b);//沒有m.c m.d//m.xx 報錯,就像方法里面的局部變量一樣不可以使用對象或類名訪問} }運行結果:
static Person c=4 no static Person a=4 person construct ----------- no static Person a=4 person construct Man a=10 Man b=10 --------- 4 1 10 102.6 程序中成員變量賦值的執行順序
2.7 靜態內部類
- 關于靜態內部類可參考此篇文章里面寫到的靜態內部類:https://www.bithachi.cn/posts/bf7b3e18.html
4.static與main
4.1 static與main方法簡介
-
由于Java虛擬機需要調用類的main()方法,所以該方法的訪問權限必須是public,又因為Java虛擬機在執行main()方法時不必創建對象,所以該方法必須是static的,該方法接收一個String類型的數組參數,該數組中保存執行Java命令時傳遞給所運行的類的參數。
-
又因為main() 方法是靜態的,我們不能直接訪問該類中的非靜態成員,必須創建該類的一個實例對象后,才能通過這個對象去訪問類中的非靜態成員。
命令行參數用法舉例:
public class CommandPara {public static void main(String[] args) {for (int i = 0; i < args.length; i++) {System.out.println("args[" + i + "] = " + args[i]);}} }4.2 面試題
此處,Something類的文件名叫OtherThing.java class Something { public static void main(String[] something_to_do) { System.out.println("Do something ..."); } } 上述程序是否可以正常編譯、運行?答案是可以正常編譯執行
5.final
在Java中聲明類、變量和方法時,可使用關鍵字final來修飾,表示“最終的”。
String類、System類、StringBuffer類
比如:Object類中的getClass()。
final double MY_PI = 3.14;
5.1 final 修飾變量—— 常量
class A {private final String INFO = "BitHachi"; //聲明常量public void print() {//The final field A.INFO cannot be assigned//INFO = "Hachi";//Error} }5.2 final修飾類
final class A{ } class B extends A{ //錯誤,不能被繼承。 }5.3 final修飾方法
class A {public final void print() {System.out.println("A");} } class B extends A {public void print() { // 錯誤,不能被重寫。System.out.println("B");} }5.4 static final—全局常量
- static final:全局常量
- static修飾的屬性強調它們只有一個,final修飾的屬性表明是一個常數(創建后不能被修改)。
- static final修飾的屬性表示一旦給值,就不可修改,并且可以通過類名訪問
5.5 面試題
面試一:
public class Something {public int addOne(final int x) {return ++x;//Error// return x + 1;//OK} } 調用addOne方法時,不能對final常量改變值,只能使用其值面試二:
public class Something { public static void main(String[] args) {Other o = new Other();new Something().addOne(o); } public void addOne(final Other o) {// o = new Other();//o是常量不可以再變o.i++;//i是變量可以變 } } class Other {public int i; }總結
以上是生活随笔為你收集整理的一篇文章全方位了解:static main final的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中的关键字:this与super
- 下一篇: 一文总结:抽象类(abstract)与接