Static Nested Class 是被聲明為靜態(static)的內部類,它可以不依賴於外部類
實例被實例化。而通常的內部類需要在外部類實例化后才能實例化,其語法看起
來挺詭異的,如下所示。
/**
* 撲克類(一副撲克)
* @author 駱昊
*
*/
public class Poker {
private static String[] suites = {"黑桃", "紅桃", "草花", "方塊"};
private static int[] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
private Card[] cards;
/**
* 構造器
*
*/
public Poker() {
cards = new Card[52];
for(int i = 0; i < suites.length; i++) {
for(int j = 0; j < faces.length; j++) {
cards[i * 13 + j] = new Card(suites[i], faces[j]);
}
}
}
/**
* 洗牌 (隨機亂序)
*
*/
public void shuffle() {
for(int i = 0, len = cards.length; i < len; i++) {
int index = (int) (Math.random() * len);
Card temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
}
/**
* 發牌
* @param index 發牌的位置
*
*/
public Card deal(int index) {
return cards[index];
}
/**
* 卡片類(一張撲克)
* [內部類]
* @author 駱昊
*
*/
public class Card {
private String suite;
// 花色
private int face;
// 點數
public Card(String suite, int face) {
this.suite = suite;
this.face = face;
}
@Override
public String toString() {
String faceStr = "";
switch(face) {
case 1: faceStr = "A"; break;
case 11: faceStr = "J"; break;
case 12: faceStr = "Q"; break;
case 13: faceStr = "K"; break;
default: faceStr = String.valueOf(face);
}
return suite + faceStr;
}
}
}
測試代碼:
class PokerTest {
public static void main(String[] args) {
Poker poker = new Poker();
poker.shuffle();
// 洗牌
Poker.Card c1 = poker.deal(0); // 發第一張牌
// 對於非靜態內部類 Card
// 只有通過其外部類 Poker 對象才能創建 Card 對象
Poker.Card c2 = poker.new Card("紅心", 1);
// 自己創建一張牌
System.out.println(c1);
// 洗牌后的第一張
System.out.println(c2);
// 打印: 紅心 A
}
}
面試題 - 下面的代碼哪些地方會產生編譯錯誤?
class Outer {class Inner {}
public static void foo() { new Inner(); }
public void bar() { new Inner(); }
public static void main(String[] args) {
new Inner();
}
}
注意:Java 中非靜態內部類對象的創建要依賴其外部類對象,上面的面試題中 foo
和 main 方法都是靜態方法,靜態方法中沒有 this,也就是說沒有所謂的外部類對
象,因此無法創建內部類對象,如果要在靜態方法中創建內部類對象,可以這樣
做:
new Outer().new Inner();
