【问题标题】:The concept of shadowing阴影的概念
【发布时间】:2010-07-21 15:10:41
【问题描述】:

给定以下代码:

public class A {
 static final long tooth = 1L;

 static long tooth(long tooth){
  System.out.println(++tooth);
  return ++tooth;
 }

 public static void main(String args[]){
  System.out.println(tooth);
  final long tooth = 2L;
  new A().tooth(tooth);
  System.out.println(tooth);
 }
}

你能解释一下阴影的概念吗? 还有一件事,main 方法的代码中实际使用了什么tooth?

我知道这是一个非常丑陋的代码,但丑陋是 SCJP 书籍作者的标准选择。

【问题讨论】:

  • What is Shadowing? 的可能重复项(虽然是 C#,但概念相同)和 What is variable shadowing used for in a Java class?
  • @Péter Török - 有没有办法确定一个问题是否与前一个问题相似?在发布之前的相关问题部分中,我没有找到(或至少我认为是)您引用的链接。
  • 众所周知,SO 搜索引擎存在缺陷。有些人实际上建议使用 google 来搜索 stackoverflow.com。但是,基于标签的搜索很有用。在这种情况下,链接的两个问题都有shadowing 标签。

标签: java shadowing


【解决方案1】:

阴影作为一个概念并没有什么神奇之处。只是对名称的引用将始终引用最近的封闭范围内的实例。在您的示例中:

public class A {
 static final long tooth#1 = 1L;

 static long tooth#2(long tooth#3){
  System.out.println(++tooth#3);
  return ++tooth#3;
 }

 public static void main(String args[]){
  System.out.println(tooth#1);
  final long tooth#4 = 2L;
  new A().tooth#2(tooth#4);
  System.out.println(tooth#4);
}

}

我已经用“tooth#N”的形式为每个实例添加了一个数字注释。基本上,任何已经在其他地方定义的名称的引入都会使该范围其余部分的早期定义黯然失色。

【讨论】:

  • 在我的代码中给牙齿编号是个好主意,现在我明白了。似乎我总是忘记 java 是按值传递的,这就是我正在考虑编译器返回的结果的不同结果。问题是我把牙齿#3 和牙齿#4 混淆了,对我来说有点尴尬的是牙齿#4 正在被修改,因为它被声明为静态的。
【解决方案2】:

当你在这一点上

System.out.println(tooth);

使用类属性 (static final long tooth = 1L;),然后声明一个新的 tooth,它会隐藏类属性,这意味着使用它而不是那个。

在tooth 方法中,tooth 变量作为值传递,它不会被修改,你可以通过执行 main 来看到这一点:

1
3
2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多