今天来说说Java中的最后一种内部类——静态内部类
所谓的静态内部类,自然就是用static修饰的内部类,那用static修饰过后的内部类,跟一般的内部类相比有什么特别的地方呢?
首先,它是静态的,这就意味着它的创建不依赖于外部类,创建内部类的实例不需要像普通内部类一样先创建外部类实例才能创建。
其次,有优势必然有劣势,它不能像普通内部类一样无限制的访问外部类的方法和成员变量,只能访问静态成员变量和静态方法。
话不多说,先来看个栗子:
public class StaticInnerClass { //外部类的非静态成员
private int numA = 1; //外部类的静态成员
private static int numB = 2; //静态内部类
static class Inner {
//内部类的非静态成员
private int numC = 3;
//内部类的静态成员
private static int numD = 4; public void printInner(){
System.out.println("printInner");
System.out.println(numB);//访问外部类的静态成员
System.out.println(numC);//访问内部类的非静态成员
System.out.println(numD);//访问内部类的静态成员
}
} //外部类的普通成员方法
public void printOuter(){
System.out.println("printOuter");
} public static void main(String[] args) {
StaticInnerClass outer = new StaticInnerClass();
outer.printOuter();
Inner inner = new StaticInnerClass.Inner();
inner.printInner();
System.out.println(StaticInnerClass.numB);
System.out.println(Inner.numD);
}
}
输出如下:
printOuter
printInner
2
3
4
2
4
看起来,内部类跟外部类的使用上是差不多的,更像是一个暂存在外部类中的一个类,跟外部类并没有什么太多本质上的联系,但是创建的时候需要使用Outer.Inner的方式来定义,就像给类加了一个命名空间一样。
再举个栗子来看看静态内部类和非静态内部类的区别:(知乎上看到的一段话,觉得比喻比较形象)
如果把类比喻成鸡蛋,内部类为蛋,,外部类是蛋壳。那么静态类相当于熟鸡蛋,就算蛋壳破碎(外部类没有实例化),蛋黄依然完好(内部类可以实例化);而非静态类相当于生鸡蛋,蛋壳破碎(无实例化),蛋黄也会跟着xx(不能实例化)。
至于原因?其实就是因为非静态内部类中保存有外部类的指针,所以可以无限制访问外部类的所有属性,而静态内部类则没有,所以静态内部类无法访问外部类的非静态成员和方法,仅仅是借用一下它的壳而已。
再来看一个栗子:
public class Caculate { //定义一个pair类来将两个数捆绑
static class Pair{
private int first;
private int second; public Pair(int first, int second) {
this.first = first;
this.second = second;
} public int getFirst() {
return first;
} public int getSecond() {
return second;
}
} //获取一个int数组中的最大和最小值
public static Pair getMaxMin(int[] values){
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i:values){
if (min > i) min = i;
if (max < i) max = i;
}
return new Pair(min,max);
} public static void main(String[] args){
int[] list = {1,3,5,2,77,23,25};
Caculate.Pair pair = Caculate.getMaxMin(list);
System.out.println(pair.getFirst());
System.out.println(pair.getSecond());
System.out.println(pair.first);
System.out.println(pair.second);
}
}
这里getMaxMin里需要一次返回两个值,所以用了一个Pair类来将两个数捆绑到一起,而因为这个类只在Caculate类中使用,而且两者并没有依赖关系,所以这里使用静态内部类是最合适的。
静态内部类还有很多适用的场景,这就需要大家在今后的使用中慢慢体会了。
至此,本篇讲解完毕,欢迎大家继续关注。