总体来熟,Java内部类为了从维护性的考虑,使用的并不是特别多。但是在某些情况下,类仅仅被使用一次,通常使用的就是匿名内部类。
在一个类的内部定义的类称为内部类。
内部类分为:成员内部类 静态内部类 局部内部类 匿名内部类。
顶层类(正常类)只能处于public和默认访问级别,而成员内部类可以处于public, protected, private和默认这4种访问级别;
是成员内部类的一种,用static修饰。静态内部类具有以下特点:
静态内部类:(相对应类中的一个静态变量)
内部类 变量名字 = new 内部类();
public class A {
public static class B {
private int v;
public void say() {
System.out.println("hello");
}
}
public static void main(String[] args) {
B b = new B();
}
}
class A {
private int a1; // 实例变量a1
private static int a2; // 静态变量a2
public static class B {
int b1 = a1; // 编译错误,不能直接访问外部类A的实例变量a1
int b2 = a2; // 合法,可以直接访问外部类A的静态变量a2
int b3 = A.this.a1; // 不合法 静态内部类中不能访问外部对象的this
}
}
class A {
public static class B {
int v1; // 实例变量
static int v2; // 静态变量
public static class C {
static int v3; // 静态内部类
}
}
}
class A {
public static class B {
int v1; // 实例变量
static int v2; // 静态变量
public static class C {
static int v3; // 静态内部类
int v4;
}
}
}
public class Tester {
public void test() {
A.B b = new A.B();
A.B.C c = new A.B.C();
b.v1 = 1;
v.v2 = 1;
A.B.v1 = 1; // 编译错误
A.B.v2 = 1; // 合法
A.B.C.v3 = 1; // 合法
}
}
成员内部类是依赖于外部类的对象而存在的;
外部类.内部类 var = new 外部类().内部类();
例子:InstanceOutterClass.java
Outer.InnerTool tool = new Outer().new InnerTool();
等价于:
Outer outer = new Outer();
Outer.InnerTool tool = outer.new InnerTool();
以下代码会导致编译错误:
Outer.InnerTool tool = new Outer.InnerTool();
public class A {
private int a1;
public int a1;
static int a1;
public A(int a1, int a2) {
this.a1 = a1;
this.a2 = a2;
}
protected int methodA() {
return a1 * a2;
}
class B {
int b1 = a1; // 直接访问private的a1
int b2 = a2; // 直接访问public的a2
int b3 = a3; // 直接访问static的a3
int b4 = A.this.a1; // 访问类A的当前实例中的a1
int b5 = methodA(); // 访问methodA()方法
}
public static void main(String args[]) {
A.B b = new A(1, 2).new B();
System.out.println("b.b1=" + b.b1); // 打印b.b1=1;
System.out.println("b.b2=" + b.b2); // 打印b.b2=2;
System.out.println("b.b3=" + b.b3); // 打印b.b3=0;
System.out.println("b.b4=" + b.b4); // 打印b.b4=3;
System.out.println("b.b5=" + b.b5); // 打印b.b5=2;
}
}
class A {
class B {
private int b1 = 1;
public int b2 = 2;
class C {
}
}
public void test() {
int v1 = b1; // invalid
int v2 = b2; // invalid
B.C c1 = new C(); // invalid
B b = new B(); // valid
int v3 = b.b1; // valid
int v4 = b.b2; // valid
B.C c2 = b.new C(); // valid
B.C c3 = new B().new C(); // valid
}
}
例子:LocalOutterClass.java
局部内部类只能在当前方法中使用。
class A {
B b = new B(); // 编译错误;
public void method() {
class B {
int v1;
int v2;
class C {
int v3;
}
}
B b = new B(); // 合法
B.C c = b.new C(); // 合法
}
}
class A {
public void method() {
class B {
static int v1; // 编译错误
int v2; // 合法
static class C { // 编译错误
int v3;
}
}
}
}
public class Hello {
public void test() {
// 假如A是同包下的一个接口,有一个抽象方法go
A a = new A() {
public void go() {
System.out.println("gogogo");
}
};
}
}
声明的位置:
实例化方式:
外部类访问内部类:
内部类访问外部类:
实例内部类:可以直接访问外部类的所有成员;如果实例内部类B与外部类A包含同名的成员,那么在类B中, this.v表示类B的成员,A.this.v表示类A的成员。
局部内部类:可以直接访问外部类的所有成员, 访问所在方法中的final类型的参数和变量;
[1] 为什么Java内部类要设计成静态和非静态两种?
https://www.zhihu.com/question/28197253
[2]深入浅析Java中Static Class及静态内部类和非静态内部类的不同
http://www.jb51.net/article/74838.htm