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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵然 中级黑马   /  2013-6-16 20:47  /  1692 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

为什么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();
        }
}

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1

查看全部评分

7 个回复

倒序浏览
不太清楚,楼主要表达什么意思,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表示的整形值就被改变了。

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1

查看全部评分

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

谢谢啦  明白了
回复 使用道具 举报
为什么没有编辑键了啊  这样咋改成已解决啊  愁  
回复 使用道具 举报
通知斑竹帮助您修改,然后大哥,我对不起您,上面说的有部分有错误,就是定义 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. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1

查看全部评分

回复 使用道具 举报
楼主您好~帖子长时间未作出回答,我已经将您的帖子改成已解决。如果有问题的话可以私密我哦~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马