目录
Java中四种嵌套类对比
Java中有四种嵌套类:
- 静态内部类 提供一些和外部类关联性的静态功能,如果不需要访问外部类的实例,优先考虑用静态内部类 例如,Map中的Map.Entry<K,V>
- 成员内部类 提供一些和外部类关联性的非静态功能,因为是非static声明,每个内部实例都会包含一个额外的指向外部类对象的引用。例如,HashMap中的KeyIterator、ValueIterator、EntryIterator等等。
- 匿名内部类 可以理解为简单版本的继承,方便实现仅当前外部类中使用。例如,重新实现Comparable中的compareTo方法,用于排序等
- 局部内部类 仅外部类的定义方法内中使用,比方继承某个类,实现仅当前方法需要的方法。
四种嵌套类对比 | 静态内部类 | 成员内部类 | 匿名内部类 | 局部内部类 |
---|---|---|---|---|
定义位置 | 成员变量 | 成员变量 | 成员变量或者成员方法内 | 成员方法内 |
内部类有明确类名 | 有 | 有 | 无 | 有 |
编译后类名 | 外部类名+$+内部类名 | 外部类名+$+内部类名 | 外部类名+$+数字编号 | 外部类名+$+序号+内部类名 |
内部类有构造函数 | 有 | 有 | 无 | 有 |
类修饰符 | final、abstract、static | final、abstract | 无 | final、abstract |
内部类访问修饰符修饰 | 可 | 可 | 否 | 否 |
内部类访问外部静态属性 | 可 | 可 | 可 | 可 |
内部类访问外部静态方法 | 可 | 可 | 可 | 可 |
内部类访问外部非静态属性 | 否 | 可 OuterClass.this.xxx; | final属性:OuterClass.this.xxx; 非final属性:否 | 可 |
内部类访问外部非静态方法 | 否 | 可 OuterClass.this.YYY(); | 否 | 可 |
外部类访问内部静态属性 | 可 | 可,必须是static final | 否 | 可 |
外部类访问内部静态方法 | 可 | 否,内部类无法定义静态方法 | 否 | 否,内部类无法定义静态方法 |
外部类访问内部非静态属性/方法 | 需要内部类实例 | 需要内部类实例 | 否 | 可 |
Demo | OuterClass | OuterClass2 | OuterClass3 | OuterClass4 |
静态内部类
/**
* 静态内部类
* @author xuweijsnj
*/
public class OuterClass {
private final int a = 10;
private static final int b = 20;
private Inner inner = new Inner();
private void printA() {
System.out.println("OuterClass.printA:" + a);
}
private static void printB() {
System.out.print("内部类访问外部静态方法:");
System.out.println("OuterClass.printB:" + b);
}
private void printC() {
// 想要直接访问编译报错,需要一个内部类实例
// No enclosing instance of the type OuterClass.Inner is accessible in scope
// System.out.println("OuterClass.printC:" + Inner.this.c);
// Inner.this.innerPrintC();
System.out.print("外部类访问内部非静态属性:");
System.out.println("OuterClass.printC:" + inner.c);
System.out.print("外部类访问内部非静态方法:");
inner.innerPrintC();
}
private static void printD() {
System.out.print("外部类访问内部静态属性:");
System.out.println("OuterClass.printD:" + Inner.d);
System.out.print("外部类访问内部静态方法:");
Inner.innerPrintD();
}
private final static class Inner {
private Inner() {}
private final int c = 30;
private static final int d = 40;
private void innerPrintA() {
// 编译报错
// No enclosing instance of the type OuterClass is accessible in scope
// System.out.println("Inner.innerPrintA:" + OuterClass.this.a);
// OuterClass.this.printA();
System.out.println("内部类访问外部非静态属性/方法:编译报错");
}
private static void innerPrintB() {
System.out.print("内部类访问外部静态属性:");
System.out.println("Inner.innerPrintB:" + OuterClass.b);
printB();
}
private void innerPrintC() {
System.out.println("Inner.innerPrintC:" + c);
}
private static void innerPrintD() {
System.out.println("Inner.innerPrintD:" + d);
}
}
public static void main(String[] args) {
new OuterClass.Inner() .innerPrintA();
OuterClass.Inner.innerPrintB();
new OuterClass().printC();
OuterClass.printD();
}
}
成员内部类
/**
* 成员内部类
* @author xuweijsnj
*/
public class OuterClass2 {
private final int a = 10;
private static final int b = 20;
private Inner inner = new Inner();
public void printA() {
System.out.println("OuterClass2.printA:" + a);
}
public static void printB() {
System.out.println("OuterClass2.printB:" + b);
}
public void printC() {
// 想要直接访问编译报错,需要一个内部类实例
// No enclosing instance of the type OuterClass2.Inner is accessible in scope
// System.out.println("OuterClass2.printC:" + Inner.this.c);
// Inner.this.innerPrintC();
System.out.print("外部类访问内部非静态属性:");
System.out.println("OuterClass2.printC:" + inner.c);
System.out.print("外部类访问内部非静态方法:");
inner.innerPrintC();
}
public static void printD() {
System.out.print("外部类访问内部静态属性:");
System.out.println("OuterClass2.printD:" + Inner.d);
System.out.println("外部类访问内部静态方法:内部类无法定义静态方法");
}
private final class Inner {
private Inner() {}
private final int c = 30;
// 必须得是static final的才可以
private static final int d = 40;
public void innerPrintA() {
System.out.print("内部类访问外部非静态属性:");
System.out.println("Inner.innerPrintA:" + OuterClass2.this.a);
System.out.print("内部类访问外部非静态方法:");
OuterClass2.this.printA();
}
// static编译报错
// The method innerPrintB cannot be declared static; static methods can only be declared in a static or top level type
public void innerPrintB() {
System.out.print("内部类访问外部静态属性:");
System.out.println("Inner.innerPrintB:" + OuterClass2.b);
System.out.print("内部类访问外部静态方法:");
printB();
}
public void innerPrintC() {
System.out.println("Inner.innerPrintC:" + c);
}
// 编译报错
// The method innerPrintD cannot be declared static; static methods can only be declared in a static or top level type
// public static void innerPrintD() {
// System.out.println("Inner.innerPrintD:" + d);
// }
}
public static void main(String[] args) {
new OuterClass2().new Inner().innerPrintA();
new OuterClass2().new Inner().innerPrintB();
new OuterClass2().printC();
OuterClass2.printD();
}
}
匿名内部类
/**
* 匿名内部类
* @author xuweijsnj
*/
public class OuterClass3 {
private final int a = 10;
private static final int b = 20;
private void printA() {
System.out.println("OuterClass3.printA:" + a);
}
private static void printB() {
System.out.println("OuterClass3.printB:" + b);
}
public String getDate(Date date) {
return date.toString();
}
static Date date2 = new Date() {
@Override
public String toString() {
System.out.println("内部类访问外部非静态属性:" + OuterClass3.this.a);
System.out.println("内部类访问外部静态属性:" + OuterClass3.b);
System.out.print("内部类访问外部非静态方法:除非用外部类实例、但是这样就没有意义");
new OuterClass3().printA();
System.out.print("内部类访问外部静态方法:");
OuterClass3.printB();
return "";
}
};
public static void main(String[] args) {
OuterClass3 outerClass3 = new OuterClass3();
System.out.println("成员方法匿名内部类");
Date date = new Date() {
@Override
public String toString() {
System.out.println("内部类访问外部非静态属性:" + OuterClass3.this.a);
System.out.println("内部类访问外部静态属性:" + OuterClass3.b);
System.out.print("内部类访问外部非静态方法:除非用外部类实例、但是这样就没有意义");
outerClass3.printA();
System.out.print("内部类访问外部静态方法:");
OuterClass3.printB();
return "";
}
};
outerClass3.getDate(date);
System.out.println("----------------------");
System.out.println("成员变量匿名内部类");
outerClass3.getDate(date2);
}
}
局部内部类
/**
* 局部内部类
* @author xuweijsnj
*/
public class OuterClass4 {
private final int a = 10;
private static final int b = 20;
private void printA() {
System.out.println("OuterClass4.printA:" + a);
}
private static void printB() {
System.out.println("OuterClass4.printB:" + b);
}
private void print() {
final class Inner {
private final int c = 30;
// 必须得是static final的才可以
private static final int d = 40;
private Inner() {}
public void innerPrintA() {
System.out.print("内部类访问外部非静态属性:");
System.out.println("Inner.innerPrintA:" + OuterClass4.this.a);
System.out.print("内部类访问外部非静态方法:");
OuterClass4.this.printA();
}
public void innerPrintB() {
System.out.print("内部类访问外部静态属性:");
System.out.println("Inner.innerPrintB:" + OuterClass4.b);
System.out.print("内部类访问外部静态方法:");
printB();
}
public void innerPrintC() {
System.out.println("Inner.innerPrintC:" + c);
}
// 编译报错
// The method innerPrintD cannot be declared static; static methods can only be declared in a static or top level type
// public static void innerPrintD() {
// System.out.println("Inner.innerPrintD:" + d);
// }
};
Inner inner = new Inner();
inner.innerPrintA();
inner.innerPrintB();
System.out.print("外部类访问内部非静态属性:");
System.out.println("OuterClass4.printC:" + inner.c);
System.out.print("外部类访问内部非静态方法:");
inner.innerPrintC();
System.out.print("外部类访问内部静态属性:");
System.out.println("OuterClass4.printD:" + Inner.d);
System.out.println("外部类访问内部静态方法:内部类无法定义静态方法");
}
public static void main(String[] args) {
new OuterClass4().print();
}
}
本文技术菜鸟个人学习使用,如有不正欢迎指出修正。xuweijsnj