有些书上对于this的用法,是指内存中的当前对象。在构造方法初始化成员变量时,如果不用this指明,=号左边的变量常常也指的是成员变量(在传入参数同名的情况下)。但是试过,实际却不是这样。代码如下:class A {
    int i = 1;
    public A(int i) {
       i = i;                
    }
}class Test {
    public static void main(String args[]) {
          A a = new A(2);
          System.out.println(a.i);
    }
}
上述代码打印出的i的值仍然为1,但如果在构造方法中,将传参代码改为  this.i = i; 其他代码不动,则打印出的i值为2。难道 i = i 这种用法压根是错误的吗?请明白人指教!谢谢!

解决方案 »

  1.   

    难道 i = i 这种用法压根是错误的吗?
    i = i,即i=1,难道这个有错
      

  2.   

    在参数中含有与类中field同名的变量时,不加this则认为是参数中的变量(形参),加this则是类中的变量。
    这里的i=i实际上什么也没做
    正确做法是用this.i = i。
      

  3.   

    public A(int i) {
    i = i; 
    }
    说明此构造方法是无效构造方法,new对象时仅仅是在栈中生成一个局部i变量且瞬间消失。对类A的成员变量i没影响。
      

  4.   

    补充:那么类似的操作,下面的代码怎么能没问题?class classArea  {
              double x,y;          double area(double x,double y)    {  
                      double s;
                      this.x=x;        
                      y=y;
                     s=this.x*y; 
                     return s;
         }
     }class c5_11 extends classArea {
               public static void main(String[ ] args)  {
                        double a=2.2,b=3.1,z;
                        c5_11 ss=new c5_11( );
                        z=ss.area(a,b);
                        System.out.println("z="+z);
             }
    }
      

  5.   

    System.out.println(a.i);
    这个打印的i是a的一个属性
    A a = new A(2);调用了
    public A(int i) {
    i = i; 
    }
    这里面的i只是一个局部变量,这里的操作也就是把局部变量的值给自己,所以出了构造方法,i就没有了
    而this.i中的this指的是你当前new的这个对象,那么this.i中的i当然指的就是new的这个对象的属性了,即this.i就是a.i
      

  6.   

    建议你去看看C语言。用C语言的全局变量来解释就非常容易理解了。由于java没有全局变量这个概念,实际上类的成员变量,不论是static的还是非static的,都可以“看成”是全局变量,注意是看成,实际并非如此。再来看看构造方法:
    A(int i ){
       i = i;
    }这里的i是局部变量。但类A有了一个成员变量i了,在这里构造方法的入参i隐藏了类成员i。所有对i的操作都是对参数i的操作。所以必须用this.i来告诉编译器你要操作的是类的成员变量i而非构造方法的形参i。说白了,这是关于变量作用域的话题。最后用一个例子来结束:public void test(){
      
        int a = 5;
        System.out.println("this is a test method,now a = " + a);
        {
            int a = 10;//这个a隐藏了代码块外面的a
            System.out.println("enter to code block,now a = " + a); //a = 10
            a++;
        }    a++;    System.out.println("last statement of this method,now a = " + a); // a = 6
    }
    理解了这段代码自然就理解了你那个问题
      

  7.   

    A(int i ){
    i = i;
    }i = i;
    这里的i=i 一般是指的参数i。最好是this.i=i这样写。
      

  8.   

    最好是this.i=i这样写
    还有就是最好将i的访问权限定位private,然后写好getter/setter,通过对象.getter
      

  9.   

    这个和LZ你题目中的不冲突的,LZ你是想说你的y没有加this吧?
    你这里的y最后还是0.0的,你在方法里用的也是参数的那个y;
      

  10.   

    我的意思正是this的用法,而这里的y,确实是传进来的值,不是0
      

  11.   

    不过LZ说的问题我过去还真没注意过,平时为了代码规范都是加的this,
    我也记得书上是说默认是this的,奇怪了
    后头再翻翻去
      

  12.   


    是的,我知道this的用法规范,只是遇上这么个问题,还真不知道到底是什么原因,而且百度的时候确实是有理论支持,在=号左面指的是成员变量,而实际操作却不是这么回事,只是想弄清楚。若说这个理论错了,后面的程序却又说不通……犯晕了
      

  13.   

    class A {
    int i = 1;
    public A(int i) {
    this.i = i; //将A方法里的i的值赋给成员变量i
    }
    }class Test {
    public static void main(String args[]) {
    A a = new A(2);//2则赋给了a对象的成员变量i
    System.out.println(a.i);
    }
    }
      

  14.   

    你后面的那个程序怎么说不通呢,你那里用的还是参数的那个y,你对象ss 的y根本就没变的呀。
      

  15.   


    class classArea {
    double x, y; double area(double x, double y) {
    double s;
    this.x = x;
    y = y;
    s = this.x * y;
    return s;
    }
    }public class c5_11 extends classArea {
    public static void main(String[] args) {
    double a = 2.2, b = 3.1, z;
    c5_11 ss = new c5_11();
    z = ss.area(a, b);
    System.out.println("z=" + z);
    System.out.println("y=" + ss.y);
    }
    }测试结果:
    y= 0.0 的
      

  16.   


    正是,这个程序中的y=y,跟第一个道理一样,但是在main方法中,确实 把真正的形参传进去了,而第一个程序就不行
      

  17.   


    class classArea {
    double x, y; double area(double x, double y) {
    double s;
    this.x = x;
    y = y;
    s = this.x * y;
    return s;
    }
    }public class c5_11 extends classArea {
    public static void main(String[] args) {
    double a = 2.2, b = 3.1, z;
    c5_11 ss = new c5_11();
    z = ss.area(a, b);
    System.out.println("z=" + z);
    System.out.println("x=" + ss.x);
    System.out.println("y=" + ss.y);
    }
    }测试结果:
    z=6.820000000000001
    x=2.2
    y=0.0
      

  18.   


    啊,确实,那么在方法的计算过程中,怎么没有把y直接传0?还有,我在area方法中,又试了一下打印y的值,这时候却不是0了,这是怎么回事?
      

  19.   

    在return前打印的话就是打印的参数,你area方法中的 y = y;左边的那个也是参数。
    说到底还是没有引用到对象的 y
    但你两个例子没有什么冲突的呀
      

  20.   

    你的area方法内部的y都是你的那个参数y,在方法内部因为没有用this,你对象的y被屏蔽了。它始终是0.0
      

  21.   


    啊,我明白了,是没有冲突,在这个方法中,并没有用到成员变量,可以认为 它就是局部 变量,y=y,其实没有做什么操作,是这样的吧? 只是在方法中直接用了y,没有用this.y,如果要是用的this.y,则仍然是0.我明白了,那么,是不是意味着,““当构造方法的参数名与数据成员名相同时,将赋值号左边的标识符默认为对象的数据成员名””这个理论,根本不对?
      

  22.   

    看你的例子好像是这么一回事,我用我这机子试的结果和你一样
    不过我印象中好像那个理论是对的,我也做过实验的;
    具体的忘了
    莫非JDK版本,或者Eclipse版本有影响?
    回头我再查查去
    呵呵  细节决定成败
    楼主加油
      

  23.   

    我现在已经转战c#阵营了
    呵呵  Java 都忘得差不多了
    不过使用对Java有那么一股莫名的好感
    莫非这就是所谓的初恋
    呵呵
      

  24.   


    为了排除JDK版本问题,我分别 在1.4和1.6版本上做过,结果一样。谢谢全程相助,非常感谢!赶时间,晚上回来结帖!!
    再次感谢!
      

  25.   

    class A 
    {
    int i = 1;
    public A(int i){i = i; }}
    class Test 
    {
    public static void main(String args[]) 
    {
    A a = new A(2);
    System.out.println(a.i);}}
    可以看的出这个结果肯定是1,为什么呢?在Java变量有作用域的概念,也就是从开始声明这个变量到这个变量所在的范围的花括号结尾(这之中变量是有效的!),在你的构造方法中声明了一个i的变量,这个变量只在此构造方法中有效,也就是说public A(int i){i = i; }}这里的i只在你的构造方法中有效,因此当你创建这个类的实例之后访问类中的成员i这个时候i的值为一(int i = 1;),但是如果你在构造方法中机上了this也就是public A(int i){this.i = i; }}之后,i就和这个对象进行了绑定,当你创建一个对象之后,你改变这个i的值,i的值就会随着你的改变改变!
      

  26.   

    class A {
    int i = 1;
    public A(int i) {
    i = i;(这句根本不起任何作用,这句表达式中的i都代表的是局部变量,你传了个2值给他,相当于你写了个表达式2=2)
    }
    }class Test {
    public static void main(String args[]) {
    A a = new A(2);
    System.out.println(a.i);
    }
    }
      

  27.   

    事实上与等号左边右边根本没有关系,Java编译器会根据你的变量名称从最里面开始查找,只要找到同名的变量就会停止,所以你的代码中,两个i都是指参数i,而不是成员变量iprivate static int i = 0;
    public static class A {
    private static int i = 1;
    public static class B {
    private static int i = 2;
    public static class C {
    private static int i = 3;
    public C() {
    System.out.println(i);
    }
    }
    }
    }
    public static void main(String[] args) throws Exception {
    new C();
    }
    像上面的代码,i就是表示C类中的成员i,如果C没有这个成员i,则编译器会认为是B的成员i,如果还没有则认为是A的,再没有就认为是Test类的,如果还没有就认为错误。
    你只要知道编译器是从里往外找,直到找到为止。
      

  28.   

    public A(int i) {
    i = i; 
    }
    说明此构造方法是无效构造方法,new对象时仅仅是在栈中生成一个局部i变量且瞬间消失。对类A的成员变量i没影响。double area(double x,double y) { 
    double s;
    this.x=x; 
    y=y;
    s=this.x*y; 
    return s;
    }
    实际上,这个函数中的y都是参数中的那个y,并非类成员的y,在函数完成后返回,计算结果保存在了s中
      

  29.   

    构造里面的i全都指代形参,而非成员变量,所以成员变量还是初始化的1.
    用this的话就可以区分形参和成员变量,顾顺利的把形参的值赋给了成员变量.
    这就是你两种方式不同结果的原因
      

  30.   

    在java 中,代码的执行顺序是从方法内部开始的,当找到第一个变量时,编译器就会使用当前变量,否则,继续向外找,直到找到该变量,否则就会出错。
    在继承和接口中,代码的执行都是从子类开始的