Effective Java 2.0程序员@IT·互联网

Effective Java 2.0_Java中的静态内部类_I

2016-10-08  本文已影响56人  SnailTyan

文章作者:Tyan
博客:noahsnail.com

1. 什么是静态内部类

在Java中有静态代码块、静态变量、静态方法,当然也有静态类,但Java中的静态类只能是Java的内部类,也称为静态嵌套类。静态内部类的定义如下:

public class OuterClass {
    
    static class StaticInnerClass {
        ...
    }
}

在介绍静态内部类之前,首先要弄清楚静态内部类与Java其它内部类的区别。

2. 内部类

什么是内部类?将一个类的定义放在另一个类的内部,就是内部类。Java的内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。

2.1 成员内部类

成员内部类是最普通的内部类,就是一个普通的类定义在另一个类的内部,形式如下:

public class OuterClass {
    
    class InnerClass {
        ...
    }
}

注:

成员内部类的创建形式如下:

//定义成员内部类的方式一
OuterClass test = new OuterClass();
InnerClass innerA = test.new InnerClass();

//定义成员内部类的方式二
OuterClass.InnerClass  innerB = new OuterClass().new InnerClass();

2.2 局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,形式如下:

public void methodInnerClass() {
    class InnerClass {
        ...
    }
    InnerClass A = new InnerClass();
}

注:

2.3 匿名内部类

用过Swing的人应该对匿名内部类非常熟悉,Swing中使用了大量的匿名内部类。匿名内部类的形式如下:

Button button = new Button();
button.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        ...             
    }
            
});

注:

2.4 静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。其定义形式如下:

public class OuterClass {
    
    static class StaticInnerClass {
        ...
    }
}

注:

2.5 静态内部类与其它内部类的区别

静态内部类与其它内部类最大的区别在于非静态内部类在编译完成之后会隐含地保存一个引用,该引用是指向创建它的外部类,但是静态内部类却没有。静态内部类只是嵌套在外部类中,因此也被称为嵌套内部类。

2.6 为什么要使用内部类

3. 为什么要使用静态内部类

使用静态内部类主要是因为静态内部类的两个优点:

以下面的例子为例:将Builder放在NutritionFacts的内部,说明二者之间有一定的关系,比起将两个类分开要好很多,因此增强了类的封装性。其次,二者放在一起,能很明显的看出Builder类是用来创建NutritionFacts类的,提高了代码的可读性。

4. 静态内部类的例子

静态内部类的创建:

//Builder Pattern
public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    public static class Builder {
        // Required parameters
        private final int servingSize;
        private final int servings;
        // Optional parameters - initialized to default values
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val) {
            calories = val;
            return this;
        }

        public Builder fat(int val) {
            fat = val;
            return this;
        }

        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }

        public Builder sodium(int val) {
            sodium = val;
            return this;
        }

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}

静态内部类的使用:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

参考资料

1、Effective Java 2.0

2、http://www.cnblogs.com/chenssy/p/3388487.html

3、http://www.cnblogs.com/dolphin0520/p/3811445.html

4、http://book.51cto.com/art/201202/317517.htm

上一篇 下一篇

猜你喜欢

热点阅读