您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java中static關鍵字和內部類如何使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java中static關鍵字和內部類如何使用”吧!
在Java中,被static修飾的成員,稱之為靜態成員,也可以稱為類成員,其不屬于某個具體的對象,是所有對象所共享的。
static修飾的成員變量,稱為靜態成員變量
【靜態成員變量特性】:
不屬于某個具體的對象,是類的屬性,所有對象共享的,不存儲在某個對象的空間中
既可以通過對象引用訪問(不推薦使用),也可以通過類名訪問,但一般更推薦使用類名訪問
類變量存儲在方法區當中
生命周期伴隨類的一生(即:隨類的加載而創建,隨類的卸載而銷毀)
public class Student{ public String name; public String gender; public int age; public double score; public static String classRoom = "rj2104"; public Student(String name, String gender, int age, double score) { this.name = name; this.gender = gender; this.age = age; this.score = score; } // ... public static void main(String[] args) { // 靜態成員變量可以直接通過類名訪問 System.out.println(Student.classRoom); Student s1 = new Student("Li leilei", "男", 18, 3.8); Student s2 = new Student("Han MeiMei", "女", 19, 4.0); Student s3 = new Student("Jim", "男", 18, 2.6); // 也可以通過對象訪問:但是classRoom是三個對象共享的 System.out.println(s1.classRoom); System.out.println(s2.classRoom); System.out.println(s3.classRoom); } }
一般類中的數據成員都設置為private,而成員方法設置為public,
Java中,被static修飾的成員方法稱為靜態成員方法,是類的方法,不是某個對象所特有的。
靜態成員一般是通過靜態方法來訪問的。
public class Student2{ // ... private static String classRoom = "rj2104"; // ... public static String getClassRoom(){ return classRoom; } } class TestStudent { public static void main(String[] args) { System.out.println(Student2.getClassRoom()); } }
【靜態方法特性】:
不屬于某個具體的對象,是類方法
可以通過對象調用,也可以通過 類名.靜態方法名(…) 方式調用,更推薦使用后者
不能在靜態方法中訪問任何非靜態成員變量和非靜態成員方法;因為非靜態方法中默認有this參數,但在靜態方法中調用時候無法傳遞this引用;除非在靜態方法中新new一個對象,再通過對象引用去訪問此對象
靜態方法無法重寫,不能用來實現多態
靜態成員變量一般不會放在構造方法中來初始化,構造方法中初始化的是與對象相關的實例屬性
靜態成員變量的初始化分為兩種:就地初始化 和 靜態代碼塊初始化。
就地初始化:在定義時直接給出初始值
public class Student2{ // ... //就地初始化 private static String classRoom = "rj2104"; //... }
用靜態代碼塊完成初始化
public class Student2{ // ... private static String classRoom; //靜態代碼塊初始化 static { classRoom = "rj2104"; } // ... }
在 Java 中,可以將一個類定義在另一個類或者一個方法的內部, 前者稱為內部類,后者稱為外部類。內部類也是封裝的一種體現。
內部類和外部類共用同一個java源文件,但是經過編譯之后,內部類會形成單獨的字節碼文件, 一般形成的字節碼文件文件名為:外部類名字$內部類名字.class
public class OutClass { class InnerClass{ } } // OutClass是外部類 // InnerClass是內部類
根據內部類定義的位置不同,一般可以分為以下幾種形式:
1.成員內部類(普通內部類)
實例內部類:未被static修飾的成員內部類
靜態內部類:被static修飾的成員內部類
2.局部內部類
3.匿名內部類
即未被static修飾的成員內部類。
【注意事項】:
外部類中的任何成員都可以在實例內部類方法中直接訪問
實例內部類當中不能有靜態的成員變量;非要定義,那么只能是被static final修飾的靜態常量,常量是在程序編譯的時候就確定的
實例內部類所處的位置與外部類成員位置相同,因此也受public、private等訪問限定符的約束
實例內部類對象必須在先有外部類對象前提下才能創建
實例內部類的非靜態方法中默認包含了一個指向外部類對象的引用和一個指向自身實例內部類對象的引用
在實例內部類方法中訪問同名的成員時,優先訪問自己的,如果要訪問外部類同名的成員,必須:外部類名稱.this.同名成員 來訪問
外部類中,不能直接訪問實例內部類中的成員,如果要訪問必須先要創建內部類的對象。
public class OutClass { private int a; static int b; int c; public void methodA() { a = 10; System.out.println(a); } public static void methodB() { System.out.println(b); } // 實例內部類:未被static修飾 class InnerClass { int c; //實例內部類當中 不能有靜態的成員變量. 非要定義,那么只能是被static final修飾的 public static final int d = 6; public void methodInner() { // 在實例內部類中可以直接訪問外部類中:任意訪問限定符修飾的成員 a = 100; b = 200; methodA(); methodB(); System.out.println(d); // 如果外部類和實例內部類中具有相同名稱成員時,優先訪問的是內部類自己的 c = 300; System.out.println(c); // 如果要訪問外部類同名成員時候,必須:外部類名稱.this.同名成員名字 OutClass.this.c = 400; System.out.println(OutClass.this.c); } } public static void main(String[] args) { // 外部類:對象創建 以及 成員訪問 OutClass outClass = new OutClass(); System.out.println(outClass.a); System.out.println(outClass.b); System.out.println(outClass.c); outClass.methodA(); outClass.methodB(); System.out.println("=============實例內部類的訪問============="); // 要訪問實例內部類中成員,必須要創建實例內部類的對象 // 而普通內部類定義與外部類成員定義位置相同,因此創建實例內部類對象時必須借助外部類 // 創建實例內部類對象 OutClass.InnerClass innerClass1 = new OutClass().new InnerClass(); innerClass1.methodInner(); // 上述語法比較怪異,也可以先將外部類對象先創建出來,然后再創建實例內部類對象 OutClass.InnerClass innerClass2 = outClass.new InnerClass(); innerClass2.methodInner(); } }
被static修飾的內部成員類稱為靜態內部類。、
【注意事項】:
在靜態內部類中只能訪問外部類中的靜態成員,除非在內部類當中new一個外部類的對象,通過外部類對象的引用去訪問其中的非靜態成員。
創建靜態內部類對象時,不需要先創建外部類對象
public class OuterClass2 { public int data1 = 1; int data2 = 2; public static int data3 = 3; public void test() { System.out.println("out::test()"); } // 靜態內部類:被static修飾的成員內部類 static class InnerClass2 { public int data4 = 4; int data5 = 5; public static int data6 = 6; public void func() { System.out.println("out::func()"); //test(); // 編譯失敗,在靜態內部類中不能直接訪問外部類中的非靜態成員 //System.out.println(data1); //System.out.println(data2); //外部類的非靜態成員,需要通過外部類的對象的引用才能訪問。 OuterClass2 outerClass = new OuterClass2(); System.out.println(outerClass.data1); System.out.println(outerClass.data2); outerClass.test(); // 在靜態內部類中只能訪問外部類的靜態成員 System.out.println(data3); System.out.println(data4); System.out.println(data5); System.out.println(data5); System.out.println(data6); } } public static void main(String[] args) { // 靜態內部類對象創建 和 成員訪問 OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2(); innerClass2.func(); } }
定義在外部類的方法體或者{ }中,一般使用的非常少。
【注意事項】
局部內部類只能在所定義的方法體內部使用
不能被public、static等修飾符修飾
局部內部類生成的字節碼文件稍有區別:外部類名字$數字內部類名字.class
ppublic class OutClass { int a = 10; public void method(){ int b = 10; // 局部內部類:定義在方法體內部 // 不能被public、static等訪問限定符修飾 class InnerClass{ public void methodInnerClass(){ System.out.println(a); System.out.println(b); } } // 只能在該方法體內部使用,其他位置都不能用 InnerClass innerClass = new InnerClass(); innerClass.methodInnerClass(); } public static void main(String[] args) { // OutClass.InnerClass innerClass = null; 編譯失敗 } }
匿名內部類,就是沒有名字的一種嵌套類
匿名內部類形成的字節碼文件文件名為:外部類名字$數字.class
4.1 使用匿名內部的好處與演示
在實際開發中,我們會遇到下面的情況:
一個接口/類的方法的某個執行過程在程序中只會執行一次,但為了使用它,我們需要創建它的實現類/子類去實現/重寫方法。
代碼中為了這一次的使用去創建一個類,未免太過麻煩,此時就可以使用匿名內部類來解決這個問題
首先來看我們正常的實現邏輯,假設有一個接口,接口當中只有一個方法
public interface Interface { void show(); }
為了使用該接口的show方法,我們需要去創建一個實現類,重寫show方法的具體實現
public class Test implements Interface{ @Override public void show() { System.out.println("只執行一次show()"); } } public class Main { public static void main(String[] args) { Test test = new Test(); test.show(); } }
如果實現類Test在程序中只使用一次,那么為了這一次的使用去創建一個類太過繁瑣,這種情況下就可以用匿名內部類來實現,無需創建新的類,減少代碼冗余,
看下面代碼:
class Main { public static void main(String[] args) { //寫法一 Interface in = new Interface() { @Override public void show() { System.out.println("匿名內部類中重寫show()"); } }; //調用接口方法 in.show(); //寫法二 new Interface() { @Override public void show() { System.out.println("匿名內部類中重寫show()"); } }.show();//調用接口方法 } }
4.2 匿名內部類的定義格式和使用
定義格式1:
接口名稱 引用名 = new 接口名稱() {
// 覆蓋重寫所有抽象方法
};
引用名.方法調用
定義格式2:
new 接口名稱() {
// 覆蓋重寫所有抽象方法
}.方法調用;
對格式“new 接口名稱() {…}”的理解:
new代表創建一個新的對象對象
接口名稱就是匿名內部類需要實現哪個接口
{…}中是匿名內部類的內容
【注意事項】:
匿名內部類,在【創建對象】的時候,只能使用唯一 一次。
匿名對象,在【調用方法】的時候,只能調用唯一 一次。
匿名內部類是省略了【實現類/子類名稱】,但是匿名對象是省略了【對象名稱】
匿名內部類可以用在具體類、抽象類、接口上,且對方法個數沒有要求。
public class Class { public void show(String s){ System.out.println("Class::show()"); } } public abstract class AbstractClass { abstract void show(String s); } public interface Interface { void show(String s); } public class TestDome { public static void main(String[] args) { //重寫普通類的方法 new Class(){ @Override public void show(String s) { System.out.println(s); } }.show("普通類"); //重寫抽象類的抽象方法 new AbstractClass(){ @Override void show(String s) { System.out.println(s); } }.show("抽象類"); //實現接口的抽象方法 new Interface(){ @Override public void show(String s) { System.out.println(s); } }.show("接口"); } }
執行結果:
感謝各位的閱讀,以上就是“Java中static關鍵字和內部類如何使用”的內容了,經過本文的學習后,相信大家對Java中static關鍵字和內部類如何使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。