您好,登錄后才能下訂單哦!
這篇文章主要介紹了Java的static關(guān)鍵字和內(nèi)部類怎么使用的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java的static關(guān)鍵字和內(nèi)部類怎么使用文章都會有所收獲,下面我們一起來看看吧。
在Java中,被static修飾的成員,稱之為靜態(tài)成員,也可以稱為類成員,其不屬于某個具體的對象,是所有對象所共享的。
static修飾的成員變量,稱為靜態(tài)成員變量
【靜態(tài)成員變量特性】:
不屬于某個具體的對象,是類的屬性,所有對象共享的,不存儲在某個對象的空間中
既可以通過對象引用訪問(不推薦使用),也可以通過類名訪問,但一般更推薦使用類名訪問
類變量存儲在方法區(qū)當(dāng)中
生命周期伴隨類的一生(即:隨類的加載而創(chuàng)建,隨類的卸載而銷毀)
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) { // 靜態(tài)成員變量可以直接通過類名訪問 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); } }
一般類中的數(shù)據(jù)成員都設(shè)置為private,而成員方法設(shè)置為public,
Java中,被static修飾的成員方法稱為靜態(tài)成員方法,是類的方法,不是某個對象所特有的。
靜態(tài)成員一般是通過靜態(tài)方法來訪問的。
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()); } }
【靜態(tài)方法特性】:
不屬于某個具體的對象,是類方法
可以通過對象調(diào)用,也可以通過 類名.靜態(tài)方法名(…) 方式調(diào)用,更推薦使用后者
不能在靜態(tài)方法中訪問任何非靜態(tài)成員變量和非靜態(tài)成員方法;因為非靜態(tài)方法中默認(rèn)有this參數(shù),但在靜態(tài)方法中調(diào)用時候無法傳遞this引用;除非在靜態(tài)方法中新new一個對象,再通過對象引用去訪問此對象
靜態(tài)方法無法重寫,不能用來實現(xiàn)多態(tài)
靜態(tài)成員變量一般不會放在構(gòu)造方法中來初始化,構(gòu)造方法中初始化的是與對象相關(guān)的實例屬性
靜態(tài)成員變量的初始化分為兩種:就地初始化 和 靜態(tài)代碼塊初始化。
就地初始化:在定義時直接給出初始值
public class Student2{ // ... //就地初始化 private static String classRoom = "rj2104"; //... }
用靜態(tài)代碼塊完成初始化
public class Student2{ // ... private static String classRoom; //靜態(tài)代碼塊初始化 static { classRoom = "rj2104"; } // ... }
在 Java 中,可以將一個類定義在另一個類或者一個方法的內(nèi)部, 前者稱為內(nèi)部類,后者稱為外部類。內(nèi)部類也是封裝的一種體現(xiàn)。
內(nèi)部類和外部類共用同一個java源文件,但是經(jīng)過編譯之后,內(nèi)部類會形成單獨的字節(jié)碼文件, 一般形成的字節(jié)碼文件文件名為:外部類名字$內(nèi)部類名字.class
public class OutClass { class InnerClass{ } } // OutClass是外部類 // InnerClass是內(nèi)部類
根據(jù)內(nèi)部類定義的位置不同,一般可以分為以下幾種形式:
1.成員內(nèi)部類(普通內(nèi)部類)
實例內(nèi)部類:未被static修飾的成員內(nèi)部類
靜態(tài)內(nèi)部類:被static修飾的成員內(nèi)部類
2.局部內(nèi)部類
3.匿名內(nèi)部類
即未被static修飾的成員內(nèi)部類。
【注意事項】:
外部類中的任何成員都可以在實例內(nèi)部類方法中直接訪問
實例內(nèi)部類當(dāng)中不能有靜態(tài)的成員變量;非要定義,那么只能是被static final修飾的靜態(tài)常量,常量是在程序編譯的時候就確定的
實例內(nèi)部類所處的位置與外部類成員位置相同,因此也受public、private等訪問限定符的約束
實例內(nèi)部類對象必須在先有外部類對象前提下才能創(chuàng)建
實例內(nèi)部類的非靜態(tài)方法中默認(rèn)包含了一個指向外部類對象的引用和一個指向自身實例內(nèi)部類對象的引用
在實例內(nèi)部類方法中訪問同名的成員時,優(yōu)先訪問自己的,如果要訪問外部類同名的成員,必須:外部類名稱.this.同名成員 來訪問
外部類中,不能直接訪問實例內(nèi)部類中的成員,如果要訪問必須先要創(chuàng)建內(nèi)部類的對象。
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); } // 實例內(nèi)部類:未被static修飾 class InnerClass { int c; //實例內(nèi)部類當(dāng)中 不能有靜態(tài)的成員變量. 非要定義,那么只能是被static final修飾的 public static final int d = 6; public void methodInner() { // 在實例內(nèi)部類中可以直接訪問外部類中:任意訪問限定符修飾的成員 a = 100; b = 200; methodA(); methodB(); System.out.println(d); // 如果外部類和實例內(nèi)部類中具有相同名稱成員時,優(yōu)先訪問的是內(nèi)部類自己的 c = 300; System.out.println(c); // 如果要訪問外部類同名成員時候,必須:外部類名稱.this.同名成員名字 OutClass.this.c = 400; System.out.println(OutClass.this.c); } } public static void main(String[] args) { // 外部類:對象創(chuàng)建 以及 成員訪問 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("=============實例內(nèi)部類的訪問============="); // 要訪問實例內(nèi)部類中成員,必須要創(chuàng)建實例內(nèi)部類的對象 // 而普通內(nèi)部類定義與外部類成員定義位置相同,因此創(chuàng)建實例內(nèi)部類對象時必須借助外部類 // 創(chuàng)建實例內(nèi)部類對象 OutClass.InnerClass innerClass1 = new OutClass().new InnerClass(); innerClass1.methodInner(); // 上述語法比較怪異,也可以先將外部類對象先創(chuàng)建出來,然后再創(chuàng)建實例內(nèi)部類對象 OutClass.InnerClass innerClass2 = outClass.new InnerClass(); innerClass2.methodInner(); } }
被static修飾的內(nèi)部成員類稱為靜態(tài)內(nèi)部類。、
【注意事項】:
在靜態(tài)內(nèi)部類中只能訪問外部類中的靜態(tài)成員,除非在內(nèi)部類當(dāng)中new一個外部類的對象,通過外部類對象的引用去訪問其中的非靜態(tài)成員。
創(chuàng)建靜態(tài)內(nèi)部類對象時,不需要先創(chuàng)建外部類對象
public class OuterClass2 { public int data1 = 1; int data2 = 2; public static int data3 = 3; public void test() { System.out.println("out::test()"); } // 靜態(tài)內(nèi)部類:被static修飾的成員內(nèi)部類 static class InnerClass2 { public int data4 = 4; int data5 = 5; public static int data6 = 6; public void func() { System.out.println("out::func()"); //test(); // 編譯失敗,在靜態(tài)內(nèi)部類中不能直接訪問外部類中的非靜態(tài)成員 //System.out.println(data1); //System.out.println(data2); //外部類的非靜態(tài)成員,需要通過外部類的對象的引用才能訪問。 OuterClass2 outerClass = new OuterClass2(); System.out.println(outerClass.data1); System.out.println(outerClass.data2); outerClass.test(); // 在靜態(tài)內(nèi)部類中只能訪問外部類的靜態(tài)成員 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) { // 靜態(tài)內(nèi)部類對象創(chuàng)建 和 成員訪問 OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2(); innerClass2.func(); } }
定義在外部類的方法體或者{ }中,一般使用的非常少。
【注意事項】
局部內(nèi)部類只能在所定義的方法體內(nèi)部使用
不能被public、static等修飾符修飾
局部內(nèi)部類生成的字節(jié)碼文件稍有區(qū)別:外部類名字$數(shù)字內(nèi)部類名字.class
ppublic class OutClass { int a = 10; public void method(){ int b = 10; // 局部內(nèi)部類:定義在方法體內(nèi)部 // 不能被public、static等訪問限定符修飾 class InnerClass{ public void methodInnerClass(){ System.out.println(a); System.out.println(b); } } // 只能在該方法體內(nèi)部使用,其他位置都不能用 InnerClass innerClass = new InnerClass(); innerClass.methodInnerClass(); } public static void main(String[] args) { // OutClass.InnerClass innerClass = null; 編譯失敗 } }
匿名內(nèi)部類,就是沒有名字的一種嵌套類
匿名內(nèi)部類形成的字節(jié)碼文件文件名為:外部類名字$數(shù)字.class
4.1 使用匿名內(nèi)部的好處與演示
在實際開發(fā)中,我們會遇到下面的情況:
一個接口/類的方法的某個執(zhí)行過程在程序中只會執(zhí)行一次,但為了使用它,我們需要創(chuàng)建它的實現(xiàn)類/子類去實現(xiàn)/重寫方法。
代碼中為了這一次的使用去創(chuàng)建一個類,未免太過麻煩,此時就可以使用匿名內(nèi)部類來解決這個問題
首先來看我們正常的實現(xiàn)邏輯,假設(shè)有一個接口,接口當(dāng)中只有一個方法
public interface Interface { void show(); }
為了使用該接口的show方法,我們需要去創(chuàng)建一個實現(xiàn)類,重寫show方法的具體實現(xiàn)
public class Test implements Interface{ @Override public void show() { System.out.println("只執(zhí)行一次show()"); } } public class Main { public static void main(String[] args) { Test test = new Test(); test.show(); } }
如果實現(xiàn)類Test在程序中只使用一次,那么為了這一次的使用去創(chuàng)建一個類太過繁瑣,這種情況下就可以用匿名內(nèi)部類來實現(xiàn),無需創(chuàng)建新的類,減少代碼冗余,
看下面代碼:
class Main { public static void main(String[] args) { //寫法一 Interface in = new Interface() { @Override public void show() { System.out.println("匿名內(nèi)部類中重寫show()"); } }; //調(diào)用接口方法 in.show(); //寫法二 new Interface() { @Override public void show() { System.out.println("匿名內(nèi)部類中重寫show()"); } }.show();//調(diào)用接口方法 } }
4.2 匿名內(nèi)部類的定義格式和使用
定義格式1:
接口名稱 引用名 = new 接口名稱() {
// 覆蓋重寫所有抽象方法
};
引用名.方法調(diào)用
定義格式2:
new 接口名稱() {
// 覆蓋重寫所有抽象方法
}.方法調(diào)用;
對格式“new 接口名稱() {…}”的理解:
new代表創(chuàng)建一個新的對象對象
接口名稱就是匿名內(nèi)部類需要實現(xiàn)哪個接口
{…}中是匿名內(nèi)部類的內(nèi)容
【注意事項】:
匿名內(nèi)部類,在【創(chuàng)建對象】的時候,只能使用唯一 一次。
匿名對象,在【調(diào)用方法】的時候,只能調(diào)用唯一 一次。
匿名內(nèi)部類是省略了【實現(xiàn)類/子類名稱】,但是匿名對象是省略了【對象名稱】
匿名內(nèi)部類可以用在具體類、抽象類、接口上,且對方法個數(shù)沒有要求。
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("抽象類"); //實現(xiàn)接口的抽象方法 new Interface(){ @Override public void show(String s) { System.out.println(s); } }.show("接口"); } }
執(zhí)行結(jié)果:
關(guān)于“Java的static關(guān)鍵字和內(nèi)部類怎么使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Java的static關(guān)鍵字和內(nèi)部類怎么使用”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。