黑马程序员技术交流社区

标题: 内部类问题 [打印本页]

作者: 赵然    时间: 2013-6-16 20:47
标题: 内部类问题
为什么setA()方法不传变量a的时候可以修改外部类的私有变量a的值,但是传了就修改不了外部类中变量的值了?
class Outer
{
        private int a = 1;
        {
                System.out.println("外部类~~"+"a="+a);
        }
        private void pri()
        {
                System.out.println("外部类~~"+"a="+a);
        }
        class Inner
        {
                void setA(int a )
                {
                        a = 0;
                        System.out.println("外部类~~"+"a="+a);
                        pri();
                }
        }
        void setIn()
        {
                Inner in = new Inner();
                in.setA(a);
        }
}


class OuterInner
{
        public static void main(String[] args)
        {
                Outer out = new Outer();
                out.setIn();
        }
}

作者: toShareBeauty    时间: 2013-6-16 21:21
不太清楚,楼主要表达什么意思,setA() 方法被调用的时候,不可以不传参数的,那样参数列表会不匹配。下面是程序运行结果

我解释一下,第一个输出是指Outer类中的对象创建的时候,执行初始化代码块的结果
第二个打印是 Inner 对象调用 setA()函数打印的结果,因为setA()函数中 a 是局部变量,而且被改写为0,所以打印为0
但是此时Outer的成员变量a还是为1,因为setIn()函数中,in.setA(a); 这条语句,这个是值传递,也就是把成员变量a的类容,也就是a的值,传递个setA()函数中局部变量a,不是引用的传递,不改写原来成员变量的值。所以Outer中pri执行的时候,打印的成员变量a仍然是1.如果把成员变量a的定义改为 Integer a;此时传递的a就是引用传递,传递的是 a 这个对象的引用,局部变量a得到引用后,重写了a这个对象中的类容,那么此时,a表示的整形值就被改变了。

作者: toShareBeauty    时间: 2013-6-16 21:23
希望上面的回答能解决楼主的疑惑
作者: j816326    时间: 2013-6-16 21:25
想解释这个问题很简单 ,如果没有传值的话 因为在同一个类中 所以内部类可以访问本类私有的成员变量;如果传值了得话  就相当于局部变量了 所以就就近取值了 不会再调用成员变量了。
作者: 赵然    时间: 2013-6-17 09:01
toShareBeauty 发表于 2013-6-16 21:21
不太清楚,楼主要表达什么意思,setA() 方法被调用的时候,不可以不传参数的,那样参数列表会不匹配。下面 ...

谢谢啦  明白了
作者: 赵然    时间: 2013-6-17 09:12
为什么没有编辑键了啊  这样咋改成已解决啊  愁  
作者: toShareBeauty    时间: 2013-6-17 09:57
通知斑竹帮助您修改,然后大哥,我对不起您,上面说的有部分有错误,就是定义 Interge a; 可以修改成员变量的值 这个是错误的,因为 a 虽然是引用类型了,但是Integer类没有提供可以修改该类对象中成员的值的函数,所以改不了。如果是内部类,要修改成员变量的值请使用外部类名加成员名的格式,比如这个 Outer.a 这样就可以修改了。
如果两个类不是内部类外部类的关系,也不是继承关系。要想通过函数传递的方式修改另一个对象的私有成员变量,除非该对象有提供一个函数让你修改。
下面的代码中有注释
  1. class Outer
  2. {
  3.                 // 下面 1 会装箱,这条语句相当于 private Integer a = new Integer(1);
  4.                 //  这时,堆里面会有一个 Integer 的对象,程序方法区的数据区如果以前
  5.                 // 没有常数1,现在会增加一个常数1
  6.         private Integer a = 1;
  7.         {
  8.                 System.out.println("外部类~~"+"a="+a);
  9.         }
  10.         private void pri()
  11.         {
  12.                 System.out.println("外部类~~"+"a="+a);
  13.         }
  14.         class Inner
  15.         {
  16.                 void setA(Integer a )
  17.                 {
  18.                         a = 0; // 这里相当于 a = new Integer(0);因为 Integer 这个类比较特殊,没有提供设置内部成员的方法,所以改不了
  19.                         System.out.println("外部类~~"+"a="+a);
  20.                         pri();
  21.                 }
  22.         }
  23.         void setIn()
  24.         {
  25.                 Inner in = new Inner();
  26.                 in.setA(a); //
  27.         }
  28. }


  29. class OuterInner
  30. {
  31.         public static void main(String[] args)
  32.         {
  33.                 Outer out = new Outer();
  34.                 out.setIn();
  35.         }
  36. }
复制代码

作者: 孙百鑫    时间: 2013-6-22 01:41
楼主您好~帖子长时间未作出回答,我已经将您的帖子改成已解决。如果有问题的话可以私密我哦~




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