Java 中的內部類和列舉
阿新 • • 發佈:2021-02-02
Java 中的內部類
# Test.java
class A {
class B {
void hello() {
System.out.println("B");
// 例項化 A
A a = new A();
a.hello();
}
}
void hello() {
System.out.println("A");
}
}
public class Test {
public static void main (String[] args) {
// 例項化類 B
B b = new A().new B();
b.hello();
}
}
# 一個 .java 檔案中有幾個類就會生成幾個位元組碼
# 該類編譯後會生成三個位元組碼
- Test.class
- A.class
- A$B.class
# 從編譯後的位元組碼可以看到、內部類是外部類的一個屬性
# 在A類外實力化B類時、編譯器會將B類作為A類的屬性、而將A類傳遞給B類的構造器
# 介面也可以作為類的成員
class A {
private interface B {
int a = 20;
void sleep ();
}
public void hello() {
System.out.println(B.a);
class C implements B {
@Override
public void sleep() {
System.out.println("C");
}
}
C c = new C();
c.sleep();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
a.hello();
}
}
class A {
int a = 20;
class B {
int a = 10;
void hello() {
System.out.println(this.a); // a = 10;
// A.this 就是 B 類構造器中傳遞過來的 A類
System.out.println(A.this.a); // a = 20;
}
}
}
public class Test {
public static void main(String[] args) {
A.B b = new A().new B();
b.hello();
}
}
靜態內部類
# 靜態內部類等價於外部類
# 靜態內部類、只能訪問內部類的靜態成員和靜態方法
class A {
static class B {
}
}
public class Test {
public static void main(String[] args) {
// 例項化靜態內部類
A.B b =new A.B();
}
}
區域性內部類
# 在一個方法中定義的類稱為區域性內部類
# 區域性內部類只能在所在的方法中例項化
class A {
void hello() {
class B {
}
// 例項化區域性內部類
B b = new B();
}
}
匿名內部類
class A {
}
public class Test {
public static void main(String[] args) {
A a = new A() {
// 匿名內部類
};
}
}
# 編譯後的位元組碼檔案為:
- Test.class
- A.class
- Test$1.class
# 在哪個類的() 後面、分號前面、寫一對花括號、這個花括號就會被編譯器編譯成一個繼承自該類的子類
- 比如 new A() {}; 花括號中的類就被編譯為A類的子類!
列舉
# 所謂列舉、就是其值可以列舉完的值
# 每一個列舉都是 java.lang.Enum 的子類
# 所有列舉型別都會實現序列化和 comparable 介面
// 定義血型的列舉
enum BloodType {
A, B, AB, O
}
interface Say {
// 介面中的每一個欄位預設都被 public static final 修飾
// 每一個方法預設都被 public abstract 修飾
int a = 10;
}
# 對於 bloodType 這個列舉類來說
- 裡面的每一個值的型別都為 BloodType
- 每一個值都被 public static final 修飾
public static void main(String[] args) {
BloodType a = BloodType.A;
System.out.println(a); // A
System.out.println(a.equals("A")); // false
System.out.println(a.getClass());
// class cn.liuweiwei.innerclass.BloodType
}
- 針對於我們定義的每一個列舉型別、編譯器都會自動為列舉型別加入方法
- ordinal() 獲取列舉值的序號
- toString() 直接輸出列舉物件的內容
- values() **靜態方法** 返回一個數組、該陣列為所有的列舉值
- valueOf() 把一個字串、解析為該列舉型別
# 什麼是解析?什麼是格式化?
- 解析就是把字串解析為其他型別
- 格式化就是把其他型別格式化為字串
# Switch 中可以應用的型別為 int short byte Byte Integer Short Long long 和列舉(enum)
- 從 jdk 1.7 開始 switch 支援 String 型別
public static void main(String[] args) {
System.out.println(BloodType.A.ordinal()); // 0
BloodType[] types = BloodType.values();
for (BloodType bloodType : types) {
System.out.print(bloodType);// A B AB O
}
}