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

 更新时间:2017年10月26日 16:24:56   作者:SnailTyan  
这篇文章主要介绍了Java中的静态内部类详解及代码示例,具有一定参考价值,需要的朋友可以了解下。

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单例模式实现静态内部类方法示例等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • SpringBoot+React实现计算个人所得税

    SpringBoot+React实现计算个人所得税

    本文将以个人所得税的计算为例,使用React+SpringBoot+GcExcel来实现这一功能,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解下
    2023-09-09
  • spring中REST和RESTful的区别以及基本实现

    spring中REST和RESTful的区别以及基本实现

    本文主要介绍了spring中REST和RESTful的区别以及基本实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • 探讨Java中的深浅拷贝问题

    探讨Java中的深浅拷贝问题

    这个概念估计懂C++的人不会陌生,但是很多朋友并不了解,概括起来将浅拷贝就是指两个对象公用一个值,一个的改变了另一个也会随之改变,深拷贝则是两个对象值相等,但是相互独立互不影响。下面我们将关于java的浅拷贝和深拷贝做一个详细讲解
    2021-06-06
  • Spring中@Value使用详解及SPEL表达式

    Spring中@Value使用详解及SPEL表达式

    这篇文章主要介绍了Spring中@Value使用详解及SPEL表达式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Spring Boot Admin监控服务如何使用

    Spring Boot Admin监控服务如何使用

    这篇文章主要介绍了Spring Boot Admin监控服务如何使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java多线程CAS操作原理代码实例解析

    Java多线程CAS操作原理代码实例解析

    这篇文章主要介绍了Java多线程CAS操作原理代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java的反射机制---动态调用对象的简单方法

    Java的反射机制---动态调用对象的简单方法

    下面小编就为大家带来一篇Java的反射机制---动态调用对象的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • Mybatis Plus使用XML编写动态sql的超简易方法

    Mybatis Plus使用XML编写动态sql的超简易方法

    这篇文章主要介绍了Mybatis Plus使用XML编写动态sql的超简易方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • SpringMvc向request域中设置数据的方法

    SpringMvc向request域中设置数据的方法

    这篇文章主要介绍了SpringMvc向request域中设置数据的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • Java如何利用Mybatis进行数据权限控制详解

    Java如何利用Mybatis进行数据权限控制详解

    这篇文章主要介绍了Java如何利用Mybatis进行数据权限控制详解,数据权限控制最终的效果是会要求在同一个数据请求方法中,根据不同的权限返回不同的数据集,而且无需并且不能由研发编码控制。,需要的朋友可以参考下
    2019-06-06

最新评论