java提高](18)—静态内部类和非静态内部类
定义
放在一个类的内部的类我们就叫内部类。
自己从开发到现在其实用到内部类主要在两个地方会考虑用内部类:
1、使用静态内部类的单例模式
2、将Json字符串转为Bean实体的时候,也考虑创建内部类
其它比如网上说的通过内部类实现多继承,我还没有用过。这篇博客主要将静态内部类和非静态内部类中的成员内部类,至于局部内部类和匿名内部类这边就不阐述了。
一、概念
我们可以简单把内部类当成外部类的一个成员,如果你是static内部类,那么外部类不需要创建对象就可以访问你,
如果你是非静态类部类,那你就属于外部类的对象的,所以一定要先创建外部对象才能来访问你。
1、非静态内部类
成员内部类也是最普通的内部类,它是外围类的一个成员,所以它可以访问外围类的所有成员属性和方法。同样外围类也可以访问内部类的成员属性和方法。
它的主要特点是:
1、成员内部类中不能存在任何static的变量和方法
2、成员内部类是依附于外围类的对象,所以只有先创建了外围类对象才能够创建内部类对象
补充:对于成员内部内并不是完全不能出现static字段的,如果你是使用final和static同时修饰一个属性字段,并且这个字段是基本类型或者String
类型的,那么是可以编译通过的。至于原因需要了解class文件,我之前写过一篇相关博客可以参考:【JVM虚拟机】(7)---深入理解Class中-属性集合
2、静态内部类
使用static修饰的内部类我们称之为静态内部类,我们要知道只要是static修饰的类那它一定是内部类
,不可能是外部类。
静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类
的对象,但是静态内部类却没有。没有这个引用就意味着:
1、它的创建是不需要依赖于外围类的对象
2、它不能使用任何外围类的非static成员变量和方法
二、示例
有关静态内部类和非静态内部类这里做一个完整的代码演示
1、代码演示
/**
* 外部类 OutClass
*/
public class OutClass {
/**
* 外部类静态属性
*/
private static String name = "小小";
/**
* 外部类非静态属性
*/
private Integer age = 3;
/**
* @Description: 非静态内部类
*/
private class InnerClass {
// TODO 非静态内部类不能声明或定义静态成员
// private static String sex = "女";
/**
* 这里定义静态常量是不会报错的哦
*/
public static final String sex = "女";
/**
* 可以定义 普通属性
*/
private int flag = 0;
/**
* 构造函数
*/
public InnerClass() {
// 非静态内部类的非静态成员可以访问外部类的非静态变量和静态变量
System.out.println("非静态类访问外部对象的name" + name);
System.out.println("外部对象的age " + age);
}
}
/**
* @Description: 静态内部类
*/
private static class InnerStaticClass {
/**
* 静态内部类可以有静态成员和非静态成员
*/
private static String sex = "女";
private int flag = 0;
public InnerStaticClass() {
System.out.println("静态类访问外部对象的name" + name);
//静态类只能访问外部的静态成员,不能访问非静态成员
//System.out.println("外部对象的age " + age);
}
}
public static void main(String[] args) {
System.out.println("==========非静态内部类调用==========");
//new一个外部类
OutClass outClass = new OutClass();
// 通过外部类的对象new一个非静态的内部类
OutClass.InnerClass innerClass = outClass.new InnerClass();
System.out.println("==========静态内部类调用==========");
//获取静态内部类的静态属性
String sex = OutClass.InnerStaticClass.sex;
//获取静态内部类的非静态属性
OutClass.InnerStaticClass inner = new OutClass.InnerStaticClass();
System.out.println(inner.flag);
}
}
2、总结
这里在针对上面代码做一个总结
1.静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
2.静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。
3.实例化一个非静态的内部类的方法:
a.先生成一个外部类对象实例
OutClass outClass=new OutClass();
b.通过外部类的对象实例生成内部类对象
OutClass.InnerClass inner=outClass.new InnerClass();
4.实例化一个静态内部类的方法:
a.不依赖于外部类的实例,直接实例化内部类对象
OutClass.InnerStaticClass inner=new OutClass.InnerStaticClass();
b.调用内部静态类的方法或静态变量,通过类名直接调用
OutClass.InnerStaticClass.static_sex
补充
1、内部类的作用
我个人觉得主要有以下三点吧
1、内部类能够提供更好的隐蔽性
。因为我们的内部类是可以用private和protected修饰的,所以在必要的时候我们可以保证在其它类里是
无法创建当前内部类对象的。就好比我们常用的静态内部类的单例模式。
2、通过内部类可以实现多继承
。
3、代码可以更加整洁
。因为我们在创建实体类的时候,可能类中还包含其它类,如果这个类只会被当前类使用,那我们只需创建一个内部类就可以了。
2、展示一个静态类部类的单例模式
/**
* 外部类
*/
public class StaticInnerSingleton {
/**
* 私有的静态内部类
*/
private static class SingletonClassInstance{
private static final StaticInnerSingleton instance = new StaticInnerSingleton();
}
/**
* 获取单例
*/
public static StaticInnerSingleton getInstance() {
return SingletonClassInstance.instance;
}
}
我相信,无论今后的道路多么坎坷,只要抓住今天,迟早会在奋斗中尝到人生的甘甜。抓住人生中的一分一秒,胜过虚度中的一月一年!(4)