非静态内部类访问外部类同名实例属性
01.public class DiscernVariable
02.{
03. private String prop = "外部类属性";
04. private class InClass
05. {
06. private String prop = "内部类属性";
07. public void info()
08. {
09. String prop = "局部变量";
10. //通过外部类类名.this.varName 访问外部类实例属性
11. System.out.println("外部类的属性值:" + DiscernVariable.this.prop);
12. //通过this.varName 访问内部类实例的属性
13. System.out.println("内部类的属性值:" + this.prop);
14. //直接访问局部变量
15. System.out.println("局部变量的值:" + prop);
16. }
17. }
18. public void test()
19. {
20. InClass in = new InClass();
21. in.info();
22. }
23. public static void main(String[] args)
24. {
25. new DiscernVariable().test();
26. }
27.}
非静态内部类可以访问外部类private实例属性,但是反过来外部类访问内部类的private实例属性就不行了,原因在于,内部类保有外部类的对象引用,而外部类没有内部类的引用
如果要访问内部类的实例属性, 可以这样 new Inner().inProp
编译上面的程序,文件所有路径会生成两个class文件,一个是DiscernVariable,一个是DiscernVariable$InClass.class
成员内部类(包括,静态,非静态)的class文件总是这种形式: OuterClass$InnerClass.class
Java不允许在非静态类里定义静态成员(静态方法,静态属性,静态初始化块)
如果是静态内部类,同样用static修饰,这个内部类与外部类相关,属于整个外部类,而不是单独属于外部类的某个对象,因此静态内部类称为类内部类,静态类不能访问外部类的实例成员,换句话说,就是不能访问非静态的成员,只要是静态的就是对类而言,非静态就是对类的实例而言,而且它们保存的内存位置也不相同,类保存在栈区,类的实例保存在堆区
如果在外部类以处使用非静态内部类,那么就不能对内部类使用private修饰符.因为非静态内部类的对象必须寄存在外部类的对象里,因此创建非静态内部类对象之前,必须先创建 其外部类的对象.
01.public class out
02.{
03. //定义一个内部类,不使用访问控制符,即同一个包中其他类可访问该内部类
04. class In
05. {
06. public In(String msg)
07. {
08. System.out.println(msg);
09. }
10. }
11.}
01.public class CreateInnerInstance
02.{
03. public static void main(String[] args)
04. {
05. Out.In in = new Out().new In("测试信息");
06. /*
07. 上面代码可以改为如下三行代码
08. 使用OuterClass.InnerClass 的形式定义内部类变量
09. Out.In in;
10. 创建外部类实例,非静态内部类实例将寄存在该实例中
11. Out out = new Out();
12. 通过外部类实例和new来调用内部类构造器创建非静态内部类实例
13. in = out.new In("测试信息")
14. */
15. }
16.}
Out.In in = new Out().new In("测试信息"); 这样的写法真的让人觉得很怪异,但它就是合理的
01.public class SubClass extends Out.In
02.{
03. public SubClass(Out out)
04. {
05. //通过传入的Out对象显式调用In的构造器
06. out.super("hello");
07. }
08.}
非静态内部类In类的构造器必须使用外部类对象来调用,上面的super代表In类的构造器,真的很怪异的写法,不是吗?要使用内部类,必须先创建它的外部类
Java还支持在方法体里定义类,即局部类,就是局部变量一样,并可以定义局部类的子类,即继承一个局部类的另一个局部类
01.<pre class="java" name="code">public class LocalInnerClass
02.{
03. public static void main(String[] args)
04. {
05. class InnerBase
06. {
07. int a;
08. }
09. class InnerSub extends InnerBase
10. {
11. int b;
12. }
13. InnerSub is = new InnerSub();
14. is.a = 5;
15. is.b = 8;
16. System.out.println("InnerSub对象的a和b属性是:" + is.a + "," + is.b);
17. }
18.}</pre><strong><br><br></strong>
输出 InnerSub对象的a和b属性是:5,8, 最后is对象也确实继承到父类的成员a