定义在其他类内部的类就被称为内部类,包含内部类的类也被称为外部类。
内部类比外部类多使用三个修饰符:private、protected、static。
非静态内部类不能拥有静态成员。
非静态内部类
格式:
public class OuterClass
{
private class InnerClass
{
//方法体
}
}
编译含有内部类的程序时,会发现在文件所在的路径下生成两个class文件,一个是OuterClass.class,另一个则是OuterClass$InnerClass.class
当在非静态内部类的方法内访问某个变量时,系统会优先在该方法内查找是否存在该名字的局部变量,如果存在就使用该变量;如果不存在,则在该方法所在的内部类中查找是否存在该名字的成员变量;如果不存在,则到内部类所在的外部类查找,如果仍不存在,则报错。
public class OuterClass
{
//找不到,最后在外部类的成员变量查找
private class InnerClass
{
//找不到,再在内部类的成员变量查找
void method()
{
//先在方法内的局部变量查找
}
}
}
如果外部类的成员变量,内部类成员变量与内部类中方法内的局部变量同名,则可以通过调用this、外部类.this作为限定区分。
public class OutClass
{
private String s = "外部类的实例变量";
private class InClass
{
private String prop = "内部类的实例变量";
public void info()
{
String prop = "局部变量";
// 通过 外部类类名.this.varName 访问外部类实例变量
System.out.println("外部类的实例变量值:"
+ OutClass.this.prop);
// 通过 this.varName 访问内部类实例的变量
System.out.println("内部类的实例变量值:" + this.prop);
// 直接访问局部变量
System.out.println("局部变量的值:" + prop);
}
}
}
如果外部类需要访问非静态内部类的成员变量,则需要显式创建非静态内部类对象来调用访问其实例变量
public class Outer
{
private int outProp = 9;
class Inner
{
private int inProp = 5;
}
public void accessInnerProp()
{
// 如需访问内部类的实例变量,必须显式创建内部类对象
System.out.println("内部类的inProp值:"
+ new Inner().inProp);
}
}
静态内部类
使用static修饰内部类,则称为静态内部类。
static可以把类的成员变成类相关,而外部类上一级为包,所以不可以使用static,而内部类上一级为外部类,所以static可以修饰内部类。
静态内部类无法访问外部类的实例变量,只能访问外部类的类成员。即时是静态内部类的实例方法也不可以,因为静态内部类对象只拥有外部类的类引用,而没有外部类对象的引用。
外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用中来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。
public class OuterClass
{
static class StaticInnerClass
{
private static int prop1 = 5;
private int prop2 = 9;
}
public void accessInnerProp()
{
// System.out.println(prop1);
// 上面代码出现错误,应改为如下形式:
// 通过类名访问静态内部类的类成员
System.out.println(StaticInnerClass.prop1);
// System.out.println(prop2);
// 上面代码出现错误,应改为如下形式:
// 通过实例访问静态内部类的实例成员
System.out.println(new StaticInnerClass().prop2);
}
}