A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

测试代码:
  1. class OuterClass
  2. {
  3.         private int prop1 = 5;
  4.         private static int prop2 = 9;
  5.         static class StaticInnerClass
  6.         {
  7.                 private static int age;
  8.                 public void accessOuterProp()
  9.                 {
  10.                         //下面代码错误,静态内部类无法访问外部类实例成员
  11.                         //System.out.println(prop1);
  12.                         //下面代码正常
  13.                         System.out.println(prop2);
  14.                 }
  15.         }
  16. }
  17. class TestStaticInnerClass
  18. {
  19.         public static void main(String[] args)
  20.         {
  21.                 OuterClass.StaticInnerClass in = new OuterClass.StaticInnerClass();
  22.                 in.accessOuterProp();
  23.         }
  24. }
复制代码
问题:
       为什么静态内部类的实例方法也不能访问外部类的实例属性呢?那么,该如何访问prop1这个变量的值呢?

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

6 个回复

倒序浏览
得好好看看关于内部类的知识了,我以前也是花了好长时间才理清了呢(磨刀不误砍柴工),具体看下边
对于外部类的那些非静态的成员变量与成员方法,在静态内部类中是无法访问的,这就是静态内部类的最大使用限制。
静态内部类在使用上有很多的限制的:
首先在静态成员(包括静态变量与静态成员)的定义上。一般情况下,如果一个内部类不是被定义成静态内部类,那么在定义成员变量或者成员方法的时候,是不能够被定义成静态成员变量与静态成员方法的。也就是说,在非静态内部类中不可以声明静态成员。如现在在一个student类中定义了一个内部类age,如果没有将这个类利用static关键字修饰,即没有定义为静态类,那么在这个内部类中如果要利用static关键字来修饰某个成员方法或者成员变量是不允许的。在编译的时候就通不过。故程序开发人员需要注意,只有将某个内部类修饰为静态类,然后才能够在这个类中定义静态的成员变量与成员方法。这是静态内部类都有的一个特性。也正是因为这个原因,有时候少了这个静态的内部类,很多工作就无法完成。或者说要绕一个大圈才能够实现某个用户的需求。这也是静态的内部类之所以要存在的一个重要原因。
其次在成员的引用上,有比较大的限制。一般的非静态内部类,可以随意的访问外部类中的成员变量与成员方法。即使这些成员方法被修饰为private(私有的成员变量或者方法),其非静态内部类都可以随意的访问。则是非静态内部类的特权。因为在其他类中是无法访问被定义为私有的成员变量或则方法。但是如果一个内部类被定义为静态的,那么在银用外部类的成员方法或则成员变量的时候,就会有诸多的限制。如不能够从静态内部类的对象中访问外部类的非静态成员(包括成员变量与成员方法)。这是什么意思呢?如果在外部类中定义了两个变量,一个是非静态的变量,一个是静态的变量。那么在静态内部类中,无论在成员方法内部还是在其他地方,都只能够引用外部类中的静态的变量,而不能够访问非静态的变量。在静态内部类中,可以定义静态的方法(也只有在静态的内部类中可以定义静态的方法),在静态方法中引用外部类的成员。但是无论在内部类的什么地方引用,有一个共同点,即都只能够引用外部类中的静态成员方法或者成员变量。对于那些非静态的成员变量与成员方法,在静态内部类中是无法访问的。这就是静态内部类的最大使用限制。在普通的非静态内部类中是没有这个限制的。也正是这个原因,决定了静态内部类只应用在一些特定的场合。其应用范围远远没有像非静态的内部类那样广泛。

加油啦!

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报
你在代码前,创建对象的引用OuterClass oc = new OuterClass(); 这样就可以访问到数据了,因为它是非静态数据
回复 使用道具 举报
Static修饰内部类,使内部类变成是外部类类相关的。属于整个外部类,而不是单独属于外部类的某个对象。因为静态内部类是外部类的类相关的,而不是外部类的对象相关的。静态内部类的对象不是寄存在外部类对象里,而是寄存在外部类的类本身中,也就是说,当静态内部类的对象存在时,并不存在一个被它寄存的外部类对象,静态内部类的对象里只有外部类的类引用,没有外部类的对象引用,如果允许静态内部类的实例方法访问外部类的实例成员,但找不到被寄存的外部类对象,将引起错误

如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。也就是说这个内部类会优先与外部类中的其他实例成员先执行,这时候外部类中的其他实例成员还不存在,你就要去调用,会有错误的
你要是想要访问prop1属性,同prop12可以把它也变成静态的,这样就可以访问了
你可以看看下面的博文,很不错的,不过有点绕
http://blog.csdn.net/renyuanchunby/article/details/7002992

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报
pro1前面加上static就可以访问了。
静态内部类,不能访问外部的非静态对象。
因为在编译的顺序是静态对象->构造函数->成员变量
回复 使用道具 举报
因为内部类是静态的,当调用外部类时,内部类首先被加载,而prop1是非静态的,内部类加载时,prop1还未存在。所以当引用prop1时,编译时会出错。
回复 使用道具 举报
  1. class OuterClass
  2. {
  3.         //这里是对象属性,不能被静态成员
  4.                 //private int prop1 = 5;
  5.                 //这里改成静态成员就能自由引用了,或者在下面引用时,通过外部类对象调用
  6.                 static int prop1 = 5;
  7.         private static int prop2 = 9;
  8.         static class StaticInnerClass
  9.         {
  10.                 private static int age;
  11.                 public void accessOuterProp()
  12.                 {
  13.                         //引用的是对象属性,故不能正常执行
  14.                                                 System.out.println(prop1);
  15.                         //下面代码正常
  16.                         System.out.println(prop2);
  17.                 }
  18.         }
  19. }
  20. class TestStaticInnerClass
  21. {
  22.         public static void main(String[] args)
  23.         {
  24.                 OuterClass.StaticInnerClass in = new OuterClass.StaticInnerClass();
  25.                 in.accessOuterProp();
  26.         }
  27. }
复制代码
先把代码修改了,为什么这么写也写了注释。其实1L的兄弟已经说的很详细了,静态内部类是不能自由调用外部类的非静态成员的,其实这个也很好理解,静态内部类说到底是个特殊的静态代码块,显然是不能直接调用其所在类(也就是外部类的)的对象属性,因为静态内部类存在的时候,不需要外部类对象存在,没有外部类对象,又怎么调用外部类对象的对象属性呢,毛之不存,皮将焉附?静态类存在的前提是有外部类就好了,并不需要外部类对象存在,故静态内部类只能调用外部类的静态成员

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马