静态嵌套类和非静态嵌套类
什么是嵌套类及内部类?
可以在一个类的内部定义另一个类, 这种类称为嵌套类(nested classes),它有两种类型:
静态嵌套类和非静态嵌套类.静态嵌套类使用很少, 最重要的是非静态嵌套类, 也即是被称作为
内部类(inner).嵌套类从JDK1.1开始引入.其中inner类又可分为三种:
(1) 在一个类中直接定义的内部类;
(2) 在一个方法中定义的内部类;
(3) 匿名内部类.
静态嵌套类和非静态嵌套类.静态嵌套类使用很少, 最重要的是非静态嵌套类, 也即是被称作为
内部类(inner).嵌套类从JDK1.1开始引入.其中inner类又可分为三种:
(1) 在一个类中直接定义的内部类;
(2) 在一个方法中定义的内部类;
(3) 匿名内部类.
1. 静态嵌套类
static修饰符使得嵌套类对象成为外部类的静态成员,与外部类直接关联。
这样静态嵌套类作为一个静态成员,仅能访问外部类的静态成员,因为外部类中的非静态成员与外部类对象相关,静态嵌套类就不能访问他们,这使得静态嵌套类的功能变的很弱,可用之处很少。
另外因为静态嵌套类是依附于外部类而非外部类对象的,所以不同的外部类对象共享一个静态嵌套类,这一点与内部类不同,可以用来包装main方法。
静态嵌套类的声明示例:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
如下所示代码为定义一个静态嵌套类
package inner;
public class StaticTest{
private static String name = "woobo";
private String num = "X001";
static class Person
{
private String address = "China";
public String mail = "kongbowoo@yahoo.com.cn";//内部类公有成员
public void display(){
//System.out.println(num);//不能直接访问外部类的非静态成员
System.out.println(name);//只能直接访问外部类的静态成员
System.out.println("Inner " + address);//访问本内部类成员。
}
}
public void printInfo(){
Person person = new Person();
person.display();
//System.out.println(mail);//不可访问
//System.out.println(address);//不可访问
System.out.println(person.address);//可以访问内部类的私有成员
System.out.println(person.mail);//可以访问内部类的公有成员
}
public static void main(String[] args){
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}
2.内部类
没有static修饰意味着一个内部类是和外部类对象关联的,也可以说一个内部类对象存在于外部类对象中,是外部类对象的一个成员,因此内部类对象可以访问外部类对象的全部成员,包括私有成员。
- 因为内部类依赖于外部类对象而存在,所以不能定义任何静态成员。
- 内部类对象可以访问外部类的所有成员变量,包括私有成员,这是Java闭包的原理;
- 因为内部类隐含对外部类的引用,所以外部类就不能被JVM的垃圾回收机制自动垃圾回收。
- 不同的外部类对象之间没有公共的内部类对象成员。
内部类的声明示例:
OuterClass.InnerClass innerObject = new OuterObject().new InnerClass();
3.变量遮蔽Shadowing
嵌套类和封装类以及局部方法区的变量作用域有重叠,如果有同名变量将发生变量遮蔽。
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
注意这里对3种不同变量的引用方式,结果如下
x = 23 //1. 局部变量 this.x = 1 //2.内部类变量 ShadowTest.this.x = 0 //3.外部类变量
内部类中this指针指向内部类自己,ShadowTest.this则指向外部类对象;
不加修饰的变量,将执行就近匹配原则;如果名称相同将发生变量遮蔽效应;为了防止隐患,内部类引用外部类对象时应使用第三种方法。

浙公网安备 33010602011771号