Java中的静态内部类详解及代码示例
作者:SnailTyan 发布时间:2021-11-25 08:50:00
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();
来源:http://blog.csdn.net/quincuntial/article/details/52756150
猜你喜欢
- 这篇文章主要介绍了Spring Boot Logback配置日志过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- ELK是三款软件的简称,分别是Elasticsearch、Logstash、Kibana组成,在发展的过程中,又有新成员Beats的加入,所
- 前言本文主要是将最近工作中遇到的一个问题进行总结分享,主要介绍的是如何让WebView中H5页面全屏播放视频。关于这个问题,做一下简单分析,
- 本文开始做一个网上商城的项目,首先从搭建环境开始,一步步
- Java 日期转换涉及的核心类:Date类、SimpleDateFormat类、Calendar类一、 Date型与long型Date型转换
- Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spri
- 在做业务开发时,遇到了一个事务不起作用的问题。大概流程是这样的,方法内部的定时任务调用了一个带事务的方法,失败后事务没有回滚。查阅资料后,问
- 在用java的io流读写文件时,总是被它的各种流能得很混乱,有40多个类,理清啦,过一段时间又混乱啦,决定整理一下!以防再忘Java输入/输
- 核心配置文件mybatis-config.xml 系统核心配置文件MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属
- 配置详情pom.xmldependency> <groupId>com.baomidou<
- 具体安装步骤,不再赘述,仅附上个人工作、学习中的对 EasyCode 的详细配置。插件链接地址:https://gitee.com/make
- 提到java里的注解,和我们平时的注释还是有很大的区别,主要是作为java特性来使用的,跟我们常见的类是同一个使用的层面。关于java注解的
- 本文实例为大家分享了C#实现扫雷游戏的具体代码,供大家参考,具体内容如下一、实验目的:1、掌握c#窗体和控件的常用属性和功能2、完成扫雷游戏
- 封装:就是把一些属性和方法封装到一个类里。 继承:就如子类继承父类的一些属性和方法。 多态:就如一个父类有多个不同特色的子类。 这里我就不多
- 前言作为一个后端程序员,网络连接这块是一个绕不过的砍,当你在做服务器优化的时候,网络优化也是其中一环,那么作为网络连接中最基础的部分-TCP
- 一、C#对XML格式数据的解析1、用XMLDocument来解析XmlDocument xmlDocument = new XmlDocum
- 缓存淘汰算法在高并发、高性能的质量要求不断提高时,我们首先会想到的就是利用缓存予以应对。第一次请求时把计算好的结果存放在缓存中,下次遇到同样
- 输入方法第一种输入方法:scannerimport java.util.Scanner; // 导入java.util.Scannerpub
- 介绍和使用场景1)什么是消息一个事件,需要广播或者单独传递给某个接口2)为什么使用这个配置更新了,但是其他系统不知道是否更新SpringCl
- Java 获取文件大小今天写代码时需要实现获取文件大小的功能,目前有两种实现方法,一种是使用File的length()方法;另外