tags:

views:

421

answers:

10

The case of shadowing class variables is common in in Java. Eclipse will happily generate this code

public class TestClass {
    private int value;
    private String test;
    public TestClass(int value, String test) {
        super();
        this.value = value;
        this.test = test;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public String getTest() {
        return test;
    }
    public void setTest(String test) {
        this.test = test;
    }
}

Is varible shadowing ever ok?

I am considering the implementation of a coding rule saying "that shadowing will not be allowed". In the simple case above it is clear enough what is going. Add in a little more code that does something and you run the risk of missing "this" and introducing a bug.

What is the general consensis, ban shadowing, allow it sometimes or let it roll?

+16  A: 

I actually prefer the guideline "Shadowing is only allowed in constructors and setters". Everything else is not allowed.
Saves you the trouble of naming constructor arguments aValue and aTest just to avoid shadowing.

If you're using eclipse, its warnings settings can be set exactly to that option BTW.

abyx
Eclipse can actually be configured to give you an error/warning in all cases except constructors. Unfortunately, it doesn't automatically know what is a getter or setter.
MatrixFrog
@abyx: That seems a reasonable compromise.@OP: In general, this kind of shadowing is a bad idea and a maintenance issue (a lot of Java programmers even now leave `this.` off when they can, creating the ambiguity and leading to subtle bugs). But an exception for constructors, getters, and setters (provided they're *simple*, as they should be) seems reasonable.
T.J. Crowder
Shadowing in getters?
Joachim Sauer
@Joachim - I was testing your attention. thanks :)
abyx
@Joachim: I can't believe I didn't catch that. In mitigation, I hadn't had my coffee yet.
T.J. Crowder
@MatrixFrog - I just downloaded eclipse galileo. Preferences->Java->Compiler->Errors/Warnings->Name shadowing->Local variable decleration hides...->Uncheck "include constructor and setter method parameters"
abyx
my take is "shadowing this with parameters is allowed only when they are the same in the current context". the same goes for naming variables like method parameters - that way 'line' in my local context is _the same_ 'line' that a method expects, and so on.
Asaf
@abyx Okay, I guess it can figure out which methods are setters. Cool.
MatrixFrog
@Joachim Sauer. If you want to return a copy of the property (.equal but not ==) why not use shadowing? `int[] getArr(){int[] arr=new int[this.arr.length]; System.arraycopy(...); return arr;}`
KitsuneYMG
+3  A: 

I feel safe with variable shadowing when using IDEs such as Eclipse and IntelliJ IDEA which highlight fields in different colors than the local variables and also provide helpful warnings on local variable mis-uses.

Amir Moghimi
NetBeans does this as well.
cdmckay
+1  A: 

A good IDE like Eclipse shows you, in different colours and/or fonts, the attributes and the method variables of your class. Becaus of that variable shadowing is OK.

Tim Krüger
And the people doing maintenance after you are going to be using such an IDE? You're sure? Their colors are going to be set up to be clearly distinct?
T.J. Crowder
They better not regress technology-wise...
abyx
@Abyx: Perhaps they don't see it as regression. Perhaps they find the colors distracting. Or they're vision-impaired and only simple black and white work. Or...or...or... Tools are great, and we should use tools to help us, but this seems like asking for trouble.
T.J. Crowder
@T.J. - One needs tests any way, and those will make sure people don't mix members and variables up.
abyx
@ T.J. Crowder (first comment): I'm not sure. But everyone must know what he do! You can work with notepad if you want!And if you have no test coverage it is your own fault I think.
Tim Krüger
A: 

I actually set up my install of Eclipse to issue warnings for every under-qualified variable. This ensures I never forget to prefix implementation variables with this.. This has effectively preemptively solved any problem that might arise from shadowing.

You can do this by way of Preferences > Java > Compiler > Errors/Warnings >> Code Style > Unqualified access to instance field.

amphetamachine
That's a very good thing to do, but it only addresses *your* problem with shadowing. People doing maintenance after you may not have the same settings enabled, or may be using an IDE that doesn't support doing it, or may need to be doing an emergency edit in some minimalist editor.
T.J. Crowder
@T.J. Crowder - But Java isn't what I would call a minimalist language. :-)Unified? yes. Terse? hell no. It's almost impossible (for me at least) to develop unfrustratingly in a regular text editor.
amphetamachine
+1  A: 

Shadowing can be useful in simple code such as constructors getters setters and anything of the sort.

However the use of descriptive variables is really important so instead of using this

this.name = name; try this this.name = newName;

Also, if you make a habit of including this. in your code it becomes second nature and helps quite a bit with readability

CheesePls
I like the "new" prefix. Why haven't I seen more use of that?!
T.J. Crowder
Because using 'new' isn't right in a constructor, only in a setter.
abyx
@abyx: Probably, I was thinking about that too. But I can get past it. :-)
T.J. Crowder
a lot of people avoid the new- prefix because new is a reserved word and if you leave a space between new and your word it creates an object accidentally. I still like the name because I don't really have that issue.
CheesePls
A: 

I do "this" shadowing all the time. In complex places, it's useful to use an explicit this even if it doesn't shadow anything. It makes it easier to distinguish between local and class variables, from the human viewpoint (although, then it becomes an issue that you must be consistent; using this a little bit here and there but not everywhere is confusing).

In Python, you don't even have the choice: plain x is always local. Class members are self.x.

Joonas Pulakka
A: 

Well, I dont see any problem with this code. Its good that IDE is helping you to reduce the amount of code that you have to write.

Explorer
A: 

A valid case is that it provides a telling signature, so those maintaining the app Can easily see which fields are passed in the Call.

The Builder pattern is, however a better solution for maintainability.

Thorbjørn Ravn Andersen
A: 

The main justification for style rules is to make code readable, both to the original author and to others who need to maintain it. In this context, readability is about being able to easily understand what the code actually does, both at the mechanistic level and at the deeper semantic level.

In general, (apart from constructors and setters) variable hiding tends to be considered bad style because it causes the casual reader to mistake uses of locals for uses of members, and vice versa. (An IDE that highlights member names tends to mitigate this, but it is still easy to miss the distinction.) And (apart from constructors and setters) there is generally a clear semantic distinction between the local and the member with the same name, and this is best reflected by using different names.

Setters and constructors are a bit different in each of the respects above. Since setters (in particular) and constructors are simple and stylized, the hiding of the form shown is unlikely to cause a casual reader and confusion. Indeed, I would argue using only one identifier for what is essentially the same information may actually make the code easier to read.

On this basis, I would say that hiding in constructors and setters is perfectly acceptable. A style rule that rigidly insists that you should avoid hiding in this context is (IMO) pedantic and maybe counter-productive. And it is certainly out of step with what most Java coders would consider to be normal practice.

Stephen C
A: 

I do "this" shadowing all the time.

Me too. I'm for it.

EJP