黑马程序员技术交流社区

标题: 静态类的非静态方法竟然能访问静态变量 [打印本页]

作者: Teemo_Mann    时间: 2014-4-21 20:55
标题: 静态类的非静态方法竟然能访问静态变量
本帖最后由 Teemo_Mann 于 2014-4-23 00:20 编辑

今天在回顾静态类,自己试了一个奇怪的现象
  1. class Outer
  2. {
  3.         private static int a;
  4.         public void getSth(){
  5.                 System.out.println(new Inner().b);
  6.         }
  7.         static class Inner
  8.         {
  9.                 public static int b = 10;
  10.                 public void display(){
  11.                         System.out.println("woshi" + a);   //[color=Red]这个地方竟然能访问外部类的静态成员,有人能解释一下吗,我在主函数里谢了Outer.Inner.display()是不行的,说明这个类即使是静态类,方法也不会默认编程静态方法的,有人知道这个为什么能访问吗[/color]
  12.                 }

  13.         }
  14. }
复制代码

作者: anqi    时间: 2014-4-21 21:03
本帖最后由 anqi 于 2014-4-21 22:28 编辑

非静态方法本来就能访问静态变量吧。非静态方法是由对象调用,对象调用的时候类已经初始化了,类初始化的时候静态变量已经进内存,能访问没问题吧。静态内部类key看作是静态成员,所以类初始化的时候就静态类也初始化了。
什么时候不行?是访问到内存中的变量还不存在的时候。
  1. public class Demo {
  2. public static int age=0;
  3.         public void run(){
  4.                 int i=age; 访问age没问题
  5.         }
  6. }
复制代码







作者: ⒈心只霸占沵    时间: 2014-4-21 21:27
  1. package Other;
  2. class Outer
  3. {
  4.            //首先,静态内部类是可以直接访问外部类的静态成员,所以display方法访问静态成员a是可以的

  5.         private static int a;

  6.         public void getSth(){
  7.                 System.out.println(new Inner().b);
  8.         }
  9.         //因为Inner 为静态内部类,有static修饰,所以Outer类加载,Inner类也跟着加载,a也是
  10.         static class Inner
  11.         {
  12.                 public static int b = 10;

  13.                 public void display(){//这个方法是非静态的,所以只能创建对象才能调用
  14.                         System.out.println("woshi" + a);  //这里可以理解为一个类的非静态方法访问本类静态变量
  15.                 }
  16.         }
  17.         //因为display 方法非静态,所以要调用的话这样   new Outer.Inner().display();
  18. }
复制代码

作者: heheka123    时间: 2014-4-21 21:31
内部类是可以访问外部类的成员的
作者: 清风夜独醉    时间: 2014-4-21 23:19
首先你要知道静态成员是随着类的加载而加载的。当内部类的方法访问外部类的静态成员的时候,外部类的静态成员已经随着外部类的加载而加载进内存里了,所以可以直接访问。
你在主函数中调用Outer.Inner.display()报错,是因为display()方法不是静态方法,是不能直接用类名调用的,必须先创建内部类对象。因为Inner是静态的,所以外部类可以直接调用,不需创建外部类对象,那么这个display()方法的调用就是这样:new Outer.Inner().display();
作者: tacyjay在路上    时间: 2014-4-22 09:21
本帖最后由 tacyjay在路上 于 2014-4-22 09:24 编辑

额。。。静态变量,又叫类变量,作用区间就是在本类中,所以同样在本类中成员位置的静态内部类是可以访问的。

再复习一下内部类的访问规则吧。

内部类的访问规则:
<1>内部类可以直接访问外部类中的成员,包括私有。(内部类之所以可以直接访问外部类中的成员是因为内部类中持有了一个外部类的引用,格式:外部类名.this(默认不写的)//这是你的第一种情况。
<2>外部类要访问内部类,必须建立内部类对象//所以你说的第二种情况,是需要先new一下的

当内部类在成员位置上时,内部类就可以被成员修饰符所修饰:
<1>private:将内部类在外部类中进行封装;
<2>static:内部类就具备了静态的特性,即 静态内部类(当内部类被static修饰后,只能直接访问外部类中的 static成员,访问出现了局限)。
①在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();   //静态内部类调用非静态方法,需要new对象。

②在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.display();    //静态内部类调用静态方法,直接类名调用即可。所以你在主函数调用display()的前提是,要用static修饰才可以





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2