为何Java中可重复声明变量数据类型?代码示例疑问解析
为什么构造方法里声明同名变量不会报错?
嘿,这个问题其实涉及到Java里的**变量遮蔽(Variable Shadowing)**机制,我来给你拆解清楚:
首先先贴出你的代码方便分析:
public class Square { private double side; public Square(double a) { double side = a; } public double area() { return side * side; } public static void main(String[] args) { Square r = new Square(10.0); System.out.println(r.area()); } }
为什么不会报错?
你误以为同名变量会触发重复声明错误,但Java判断变量是否重复声明的核心是作用域:
- 类里的
private double side是成员变量,属于类级作用域,整个Square类的非静态方法都能访问它 - 构造方法里的
double side = a;是局部变量,属于构造方法的局部作用域,只有在构造方法内部能访问
这两个变量属于完全不同的作用域,所以编译器不会认为是重复声明——这是Java允许的行为,也就是所谓的“变量遮蔽”:局部作用域的同名变量会暂时“覆盖”成员变量,在构造方法内部直接写side时,指的是这个局部变量,而非成员变量。
代码执行的隐藏问题
不过这里有个容易踩的坑:你写这段代码的初衷应该是给成员变量side赋值,但现在的代码并没有做到!构造方法里的局部变量side赋值后,会随着构造方法执行完毕被销毁,而类的成员变量side始终保持默认值0.0。所以运行代码时,r.area()会返回0.0 * 0.0 = 0.0,而不是你预期的100.0。
正确的赋值方式
如果要给成员变量side正确赋值,有两种常用方式:
- 去掉局部变量的类型声明,直接赋值:
此时Java会优先查找成员变量,因为局部作用域里没有同名变量了。public Square(double a) { side = a; } - 用
this关键字明确指定成员变量:public Square(double a) { this.side = a; }this代表当前对象的引用,能清晰区分局部变量和成员变量,尤其在变量名相同时推荐用这种方式,代码可读性更强。
内容的提问来源于stack exchange,提问作者Bob Smith
相关产品推荐
相关产品推荐

