Variable shadowing

Variable shadowing

Today we’ll look into a rare feature of Java: variable shadowing

First, let’s define what is a shadowed field or method:

A field is considered shadowed when

  • a subclass of its declaring class declares a field with the same name and same
  • a variable having the same name and type is declared in the local scope
  • a method argument/parameter is declared with a same name and type

I Local variable shadowing

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public class MyClass

{

private int count = 10;

private void localVariable()

{

int count = 5;

System.out.println("count = "+ count);

}

public static void main(String[] args)

{

MyClass test = new MyClass();

test.localVariable();

}

}

The above code will output

count = 5

because the count local variable declared at line 7 shadows the variable count declared at class level. If we want to access the instance variable, we need to add the thiskeyword.

1

2

3

4

5

6

private void localVariable()

{

int count = 5;

System.out.println("count = "+ this.count);

}

II Method argument shadowing

This situation is very common even though we do not pay much attention to it. Below is a simple getter definition

1

2

3

4

5

6

private int count;

public void setCount(int count)

{

this.count = count;

}

The this keyword is mandatory to resolve the ambiguity. Without this, the compiler cannot know whether we are assigning the count method argument value to itself. If you remove the this keyword, you would get a compilation warning anyway.

III Superclass field shadowing

Let’s consider the following classes:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class SuperClass

{

protected String val = "SUPER_VAL";

protected void display()

{

System.out.println("val = "+this.val);

}

}

public class ChildClass extends SuperClass

{

private String val;

public ChildClass(String value) {

this.val = value;

}

public static void main(String[] args)

{

ChildClass child = new ChildClass("CHILD_VAL");

child.display();

}

}

The execution gives:

val = SUPER_VAL

The val field has been declared in the SuperClass but is shadowed in the ChildClassbecause the latter declares another field with same name and type. Although theChildClass has been instantiated with “CHILD_VAL”, the execution of child.display()gives you “SUPER_VAL”.

The reason is simple. When the child instance is created, there are 2 variables val. The one from SuperClass with value “SUPER_VAL” and the one from ChildClass with injected value “CHILD_VAL” through constructor.

When the display() method is called, since it is define in the SuperClass, it is the val field in the context of SuperClass which is used. Not surprising that the output shows “SUPER_VAL”.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class ChildClass extends SuperClass

{

private String val;

public ChildClass(String value) {

this.val = value;

super.val = value;

}

public static void main(String[] args)

{

ChildClass child = new ChildClass("CHILD_VAL");

child.display();

}

}

In the above modified code, we force the value for the hidden val field in SuperClasswith super.val = value, and the output gives:

val = CHILD_VAL

Now let’s add another class in the hierarchy

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class AncestorClass

{

protected String val = "ANCESTOR_VAL";

}

public class SuperClass extends AncestorClass

{

protected String val = "SUPER_VAL";

}

public class ChildClass extends SuperClass

{

private String val = "CHILD_VAL";

public void displayVal()

{

System.out.println("val = " + super.val);

}

public static void main(String[] args)

{

ChildClass child = new ChildClass();

child.displayVal();

}

}

Obviously, the output will display

val = SUPER_VAL

The question now is: what if we want to display the val value of AncestorClass ? Obviously the super keyword only refers to the first parent class up in the class hierarchy.

Casting comes to the rescue. Indeed we can force the this keyword representing the current class instance to a particular type in the class hierarchy !

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public class ChildClass extends SuperClass

{

private String val = "CHILD_VAL";

public void displayVal()

{

System.out.println("val = " + ((AncestorClass) this).val);

}

public static void main(String[] args)

{

ChildClass child = new ChildClass();

child.displayVal();

}

}

This time, we do have

val = ANCESTOR_VAL

时间: 2025-01-18 05:27:05

Variable shadowing的相关文章

Codeforces Gym 100513M M. Variable Shadowing 暴力

M. Variable Shadowing Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/problem/M Description In computer programming, variable shadowing occurs when a variable declared within a certain scope has the same name as a variab

codeforces Variable Shadowing 栈的模拟

//今天学校的周练赛的一道模拟的"水题",当时就是没有做出来... //哎,自己模拟的能力真的很差啊,完全是被虐的啊.555 //虽然能模拟出遇到左边的括号进入栈中,遇到右括号,全部弹出这一层, //但就是没有考虑如果两个字母不在一个括号里面,那就跪了 //1 //{ a } { b } a { a } { a } { a x { a b x } } b x //比如这组.第二个b和倒数第二个b就完全不相关,没有处理好... //最后看了大神飞蛾扑火的博客才恍然大悟,原来如此啊 //继

Java Nested Class

Normal class(Non-nested class) can only be public, abstract or final. For nested classes, static is allowed. Nested classes(private, public, protected) -> 2 Categories. 1. Static Nested Class (Very Different from C# static class) alpha: Have access t

GO 新开发者要注意的陷阱和常见错误

转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable Shadowing 不使用显式类型,无法使用"nil"来初始化变量 使用"nil" Slices and Maps Map的容量 字符

[转]50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs

http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ 50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs Go is a simple and fun language, but, like any other language, it has a few gotchas... Many of those gotc

03基础-AngularJS基础教程

0. 目录 目录 前言 正文 1 Set up 2 表达式 3 指令 ng-bind ng-init ng-non-bindable ng-show 4 作用域 双向绑定Two-way binding ng-model 5 总结 声明 1. 前言 AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了,所以AngularJS做了一些工作来来解决静态网页技术在构建动态应用上的不足. AngularJS

[转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]

Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其转载.由于文章很长,分为上下两部分,第一部分记录初级篇,第二部分记录进阶和高级篇:此为第一部分,若要看第二部分,请转至这里 感谢原文作者Kyle Quest以及翻译者影风LEY.出处见下: 原文链接:http://devs.cloudimmunity.com/gotchas-and-common-m

VJass

JassHelper 0.A.0.0 Although World Editor's Jass compiler was finally replaced by PJass using WEHelper , there were a couple of other annoyances that still needed fixing, that's the reason this project begand. Later I felt like going furt

基本语法

变量绑定 在Rust中,变量绑定 (variable bindings) 是通过let关键字声明的: let x = 5; let mut x = 5; let x: i32 = 5; let (a, b) = (3, 4); 其中变量类型如i32一般都是可以省略的,因为Rust使用了类型推断 (type inference). Rust还通过模式匹配 (pattern matching) 对变量进行解构,这允许我们同时对多个变量进行赋值. 有几点是需要特别注意的: 变量默认是不可改变的 (im