有些书上对于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 这种用法压根是错误的吗?请明白人指教!谢谢!
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 这种用法压根是错误的吗?请明白人指教!谢谢!
i = i,即i=1,难道这个有错
这里的i=i实际上什么也没做
正确做法是用this.i = i。
i = i;
}
说明此构造方法是无效构造方法,new对象时仅仅是在栈中生成一个局部i变量且瞬间消失。对类A的成员变量i没影响。
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);
}
}
这个打印的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
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
}
理解了这段代码自然就理解了你那个问题
i = i;
}i = i;
这里的i=i 一般是指的参数i。最好是this.i=i这样写。
还有就是最好将i的访问权限定位private,然后写好getter/setter,通过对象.getter
你这里的y最后还是0.0的,你在方法里用的也是参数的那个y;
我也记得书上是说默认是this的,奇怪了
后头再翻翻去
是的,我知道this的用法规范,只是遇上这么个问题,还真不知道到底是什么原因,而且百度的时候确实是有理论支持,在=号左面指的是成员变量,而实际操作却不是这么回事,只是想弄清楚。若说这个理论错了,后面的程序却又说不通……犯晕了
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);
}
}
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 的
正是,这个程序中的y=y,跟第一个道理一样,但是在main方法中,确实 把真正的形参传进去了,而第一个程序就不行
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
啊,确实,那么在方法的计算过程中,怎么没有把y直接传0?还有,我在area方法中,又试了一下打印y的值,这时候却不是0了,这是怎么回事?
说到底还是没有引用到对象的 y
但你两个例子没有什么冲突的呀
啊,我明白了,是没有冲突,在这个方法中,并没有用到成员变量,可以认为 它就是局部 变量,y=y,其实没有做什么操作,是这样的吧? 只是在方法中直接用了y,没有用this.y,如果要是用的this.y,则仍然是0.我明白了,那么,是不是意味着,““当构造方法的参数名与数据成员名相同时,将赋值号左边的标识符默认为对象的数据成员名””这个理论,根本不对?
不过我印象中好像那个理论是对的,我也做过实验的;
具体的忘了
莫非JDK版本,或者Eclipse版本有影响?
回头我再查查去
呵呵 细节决定成败
楼主加油
呵呵 Java 都忘得差不多了
不过使用对Java有那么一股莫名的好感
莫非这就是所谓的初恋
呵呵
为了排除JDK版本问题,我分别 在1.4和1.6版本上做过,结果一样。谢谢全程相助,非常感谢!赶时间,晚上回来结帖!!
再次感谢!
{
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的值就会随着你的改变改变!
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);
}
}
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类的,如果还没有就认为错误。
你只要知道编译器是从里往外找,直到找到为止。
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中
用this的话就可以区分形参和成员变量,顾顺利的把形参的值赋给了成员变量.
这就是你两种方式不同结果的原因
在继承和接口中,代码的执行都是从子类开始的