1. 程式人生 > >靜態巢狀類(Static Nested Class)和內部類(Inner Class)的不同

靜態巢狀類(Static Nested Class)和內部類(Inner Class)的不同

答: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;
        }

        @Overridepublic 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();

---------------------------靜態內部類的用法------------------------------------------------------------------

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

public class JsonUtil {

    public static final String obj2Json(Object obj, String formatStr) {
        String jsonStr = "[]";
        if (CommonUtil.isEmpty(obj)) {
            LoggerHelper.warn("傳入的Java物件為空,不能將其序列化為Json格式");
        } else {
            JsonConfig cfg = new JsonConfig();
            cfg.registerJsonValueProcessor(java.sql.Timestamp.class, new JsonValueProcessorImp(formatStr)

);
            cfg.registerJsonValueProcessor(java.util.Date.class, new JsonValueProcessorImp(formatStr));
            cfg.registerJsonValueProcessor(java.sql.Date.class, new JsonValueProcessorImp(formatStr));
            if (obj instanceof ArrayList) {
                JSONArray jsonArray = JSONArray.fromObject(obj, cfg);
                jsonStr = jsonArray.toString();
            } else {
                JSONObject jsonObject = JSONObject.fromObject(obj, cfg);
                jsonStr = jsonObject.toString();
            }
        }
        
        return jsonStr;
    }
    
    static class JsonValueProcessorImp implements JsonValueProcessor {

        /**
         * 預設的格式
         */
        private String format = "yyyy-MM-dd HH:mm:ss";

        public JsonValueProcessorImp() {
        };

        public JsonValueProcessorImp(String format) {
            this.format = format;
        }

        /**
         * 格式化陣列
         */
        public Object processArrayValue(Object value, JsonConfig jsonConfig) {
            String[] obj = {};
            if (value instanceof java.util.Date[]) {
                SimpleDateFormat sf = new SimpleDateFormat(format);
                java.util.Date[] dates = (java.util.Date[]) value;
                obj = new String[dates.length];
                for (int i = 0; i < dates.length; i++) {
                    obj[i] = sf.format(dates[i]);
                }
            }
            if (value instanceof Timestamp[]) {
                SimpleDateFormat sf = new SimpleDateFormat(format);
                Timestamp[] dates = (Timestamp[]) value;
                obj = new String[dates.length];
                for (int i = 0; i < dates.length; i++) {
                    obj[i] = sf.format(dates[i]);
                }
            }
            if (value instanceof java.sql.Date[]) {
                SimpleDateFormat sf = new SimpleDateFormat(format);
                java.sql.Date[] dates = (java.sql.Date[]) value;
                obj = new String[dates.length];
                for (int i = 0; i < dates.length; i++) {
                    obj[i] = sf.format(dates[i]);
                }
            }
            return obj;
        }

        /**
         * 格式化單一物件
         */
        public Object processObjectValue(String key, Object value,
                JsonConfig jsonConfig) {
            if(CommonUtil.isEmpty(value))
                return "";
            if (value instanceof Timestamp) {
                String str = new SimpleDateFormat(format).format((Timestamp) value);
                return str;
            } else if (value instanceof java.util.Date) {
                String str = new SimpleDateFormat(format).format((java.util.Date) value);
                return str;
            } else if (value instanceof java.sql.Date) {
                String str = new SimpleDateFormat(format).format((java.sql.Date) value);
                return str;
            }
            return value.toString();
        }

        public String getFormat() {
            return format;
        }

        public void setFormat(String format) {
            this.format = format;
        }

    }
}