Java中的静态内部类详解及代码示例

所属分类: 软件编程 / java 阅读数: 14
收藏 0 赞 0 分享

1. 什么是静态内部类

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

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

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

2. 内部类

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

2.1 成员内部类

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

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

注:

在成员内部类中,可以直接访问外部类的属性、方法,即使是private类型也可以访问,这是因为内部类持有一个外部类的引用,可以自由访问。

成员内部类中不能存在任何静态变量和静态方法。

成员内部类是依附于外部类的,只有先创建了外部类才能够创建内部类。

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

//定义成员内部类的方式一
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();
}

注:

局部内部类就像是方法里面的一个局部变量一样,不能有public、protected、private以及static修饰符。

可以直接访问外部类的属性、方法,即使是private类型也可以访问。

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 为什么要使用内部类

方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建外部类的对象。典型的情况是Effective Java 2.0中Item 2讲述的构建器模式。

使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。

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

总结

以上就是本文关于Java中的静态内部类详解及代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Java编程子类能否重写父类的静态方法探索Java单例模式实现静态内部类方法示例等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

更多精彩内容其他人还在看

Java数据类型的规则

这篇文章主要介绍了Java数据类型的规则的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring整合TimerTask实现定时任务调度

这篇文章主要介绍了Spring整合TimerTask实现定时任务调度的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解SpringMVC使用MultipartFile实现文件的上传

本篇文章主要介绍了SpringMVC使用MultipartFile实现文件的上传,本地的文件上传到资源服务器上,比较好的办法就是通过ftp上传。这里是结合SpringMVC+ftp的形式上传的,有兴趣的可以了解一下。
收藏 0 赞 0 分享

SpringMVC上传文件的三种实现方式

本篇文章主要介绍了SpringMVC上传文件的三种实现方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例

本篇文章主要介绍了微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
收藏 0 赞 0 分享

浅析Java中的继承与组合

本文将介绍组合和继承的概念及区别,并从多方面分析在写代码时如何进行选择。文中通过示例代码介绍的很详细,有需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

利用反射获取Java类中的静态变量名及变量值的简单实例

下面小编就为大家带来一篇利用反射获取Java类中的静态变量名及变量值的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java启动线程的3种方式对比分析

这篇文章主要为大家对比分析了java启动线程的3种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SpringMVC上传和解析Excel方法

这篇文章主要介绍了SpringMVC上传和解析Excel方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

JAVA中String类与StringBuffer类的区别

这篇文章主要为大家详细介绍了JAVA中String类与StringBuffer类的区别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多