views:

1449

answers:

20

One of my nasty (?) programming habits in C++ and Java is to always precede calls or accesses to members with a this. For example: this.process(this.event). A few of my students commented on this, and I'm wondering if I am teaching bad habits.

My rationale is:
1) Makes code more readable — Easier to distinguish fields from local variables.
2) Makes it easier to distinguish standard calls from static calls (especially in Java)
3) Makes me remember that this call (unless the target is final) could end up on a different target, for example in an overriding version in a subclass.

Obviously, this has zero impact on the compiled program, it's just readability. So am I making it more or less readable?

Related Question

Note: I turned it into a CW since there really isn't a correct answer.

+34  A: 

I think it's less readable, especially in environments where fields are highlighted differently from local variables. The only time I want to see "this" is when it is required, for example:

this.fieldName = fieldName

When assigning the field.

That said, if you need some way to differentiate fields for some reason, I prefer "this.fieldName" to other conventions, like "m_fieldName" or "_fieldName"

cynicalman
Most decent IDEs show a visual difference for field variables, so there's really no need to change the variable's name to show it.
Allain Lalonde
Out of curiosity: The underscore should only be used in Java in constants were camelCase is not applicable. Or am I wrong?
Georgi
@Georgi underscore can be used in Java for any identifier. 'should' is only a matter of coding convention. underscore is valid anywhere in any kind of Java identifier.
Aaron
There is not much point in doing something which the IDE does for you. i.e. hightlighting. Even web viewer and wikis do this for you now.
Peter Lawrey
+1 for pointing out the issue of syntax coloring!
Adrian
@Georgi Java can use just about any unicode character for which Character.isJavaIdentifierStart or isJavaIdentifierPart is true. W/o using random unicode values both _ and $ are valid java identifiers. It is considered very bad form to use these!
KitsuneYMG
+5  A: 

More readable, I think. I do it your way for exactly the same reasons.

jeffm
A: 

From a .Net perspective, some of the code analysis tools I used saw the "this" and immediately concluded the method could not be static. It may be something to test with Java but if it does the same there, you could be missing some performance enhancements.

Austin Salonen
Static vs instance methods have no performance difference that is significant in the real world. The difference is either 0 or 1 clock cycles depending on the method. If you care about that, then .NET is the wrong platform anyway.
Greg Beech
+1  A: 

Not a bad habit at all. I don't do it myself, but it's always a plus when I notice that someone else does it in a code review. It's a sign of quality and readability that shows the author is coding with a dedicated thought process, not just hacking away.

Tim Mooney
+15  A: 

This is a very subjective thing. Microsoft StyleCop has a rule requiring the this. qualifier (though it's C# related). Some people use underscore, some use weird hungarian notations. I personally qualify members with this. even if it's not explicitly required to avoid confusion, because there are cases when it can make one's code a bit more readable.

You may also want to check out this question:
http://stackoverflow.com/questions/111605/what-kind-of-prefix-do-you-use-for-member-variables

petr k.
My beef with this style (no pun) is that it runs against the grain of object orientation. Inside a member function and attributes and function calls should generally belong to the object and others an exception.A good naming convention is probably superior.
@saratav: I see your point however what about parameters? They are essentially local to the method and don't need to be qualified... Having 'this' lets you KNOW that it's not a param.
Neil N
+1  A: 

I would argue that what matters most is consistency. There are reasonable arguments for and against, so it's mostly a matter of taste when considering which approach.

Owen
+8  A: 

Sometimes I do like writing classes like this:

class SomeClass{
    int x;
    int y;

    SomeClass(int x, int y){
        this.x = x
        this.y = y
    }
}

This makes it easier to tell what argument is setting what member.

Jason Baker
I think this is the only time it's advisable to use "this" as a prefix.
Bill the Lizard
In C++-like languages yeah. I'd point out that other languages like python actually require it. So it's just a matter of perspective.
Jason Baker
I try to make this the only time I use the 'this' prefix.
Heath Borders
+3  A: 

In my opinion you are making it more readable. It lets potential future troubleshooters know for a fact where the function you are calling is.

Second, it is not impossible to have a function with the exact same name global or from some namespace that that gets "using"'ed into conflict. So if there is a conflict the original code author will know for certain which function they are calling.

Granted that if there are namespace conflicts some other rule of clean coding is being broken, but nobody is perfect. So I feel that any rule that does not impede productivity, has the potential to reduce errors(however minuscule a potential), and could make a future troubleshooters goal easier, is a good rule.

Sqeaky
A: 

I used to always use this... Then a coworker pointed out to me that in general we strive to reduce unnecessary code, so shouldn't that rule apply here as well?

dicroce
Do you consider it producing unnecessary code? It doesn't really increase the complexity of the program or significantly affect the AST, the same way that longer variable names don't make a difference.
Uri
But longer variable names serve a purpose. The question posed is whether this. is more akin to converting i to rowIndex, or converting retVal to returnValueThatHasBeenCreatedButNotVerifiedAndIsThereforeBeingHeldHere.
Guvante
A: 

If you are going to remove the need to add this. in front of member variables, static analysis tools such as checkstyle can be invaluable in detecting cases where member variables hide fields. By removing such cases you can remove the need to use this in the first place. That being said I prefer to ignore these warnings in the case of constructors and setters rather than having to come up with new names for the method parameters :).

With respect to static variables I find that most decent IDEs will highlight these so that you can tell them apart. It also pays to use a naming convention for things like static constants. Static analysis tools can help here by enforcing the naming conventions.

I find that there is seldom any confusion with static methods as the method signatures are often different enough to make any further differentiation unnecessary.

Peter Kelley
+1  A: 

Python folks do it all the time and almost all of them prefer it. They spell it 'self' instead of 'this'. There are ways around it putting explicit 'self' in, but the consensus is that explicit 'self' is essential to understanding the class method.

S.Lott
This makes me think that I may be getting my bad habits from smalltalk...
Uri
@Uri: I'm not sure I see how smalltalk habits bleed through to Python, but perhaps there's some veiled connection.
S.Lott
I meant that in smalltalk you have to send the message to something, even a "self msg", "super msg", etc.
Uri
@Uri: Gotcha - self.whatever in smalltalk looks a lot like self.whatever() in Python. Perfectly clear where to find the definition of whatever.
S.Lott
+1  A: 

I have to join the 'include this' camp here; I don't do it consistently, but from a maintenance standpoint the benefits are obvious. If the maintainer doesn't use an IDE for whatever reason and therefore doesn't have member fields and methods specially highlighted, then they're in for a world of scrolling pain.

Chris R
+1  A: 

"Readability"

I have found useful the use "this" specially when not using an IDE ( small quick programs )

Whem my class is large enough as to delegate some methods to a new class, replacing "this" with "otherRef" it's very easy with the most simple text editor.

ie

//Before
this.calculateMass();
this.perfornmDengerAction();
this.var = ...
this.other = ...

After the "refactor"

// after
this.calculateMass();
riskDouble.calculateMass();
riskDouble.setVar(...);
this.other = ...

When I use an IDE I don't usually use it. But I think that it makes you thing in a more OO way than just use the method.

class Employee {

        void someMethod(){
             // "this" shows somethings odd here.
             this.openConnectino() ; // uh? Why an employee has a connection???
             // After refactor, time to delegate.
             this.database.connect(); // mmhh an employee might have a DB.. well.. 
         }
     ... etc....
}

The most important as always is that if a development team decides to use it or not, that decision is respected.

OscarRyz
+2  A: 

I find that less is more. The more needlessly verbose junk you have in your code, the more problems people are going to have maintaining it. That said, having clear and consistent behavior is also important.

Russell Myers
A: 

I prefer the local assignment mode described above, but not for local method calls. And I agree with the 'consistency is the most important aspect' sentiments. I find this.something more readable, but I find consistent coding even more readable.

public void setFoo(String foo) {
    this.foo = foo; //member assignment
}

public doSomething() {
    doThat(); //member method
}

I have colleagues who prefer:

public void setFoo(String foo) {
    _foo = foo;
}
+4  A: 

3 Reasons ( Nomex suit ON)

1) Standardization

2) Readability

3) IDE

1) The biggie Not part of Sun Java code style.

(No need to have any other styles for Java.)

So don't do it ( in Java.)

This is part of the blue collar Java thing: it's always the same everywhere.

2) Readability

If you want this.to have this.this in front of every this.other this.word; do you really this.think it improves this.readability?

If there are too many methods or variable in a class for you to know if it's a member or not... refactor.

You only have member variables and you don't have global variables or functions in Java. ( In other langunages you can have pointers, array overrun, unchecked exceptions and global variables too; enjoy.)

If you want to tell if the method is in your classes parent class or not... remember to put @Override on your declarations and let the compiler tell you if you don't override correctly. super.xxxx() is standard style in Java if you want to call a parent method, otherwise leave it out.

3) IDE Anyone writing code without an IDE that understands the language and gives an outline on the sidebar can do so on their own nickel. Realizing that if it aint' language sensitive, you're trapped in the 1950's. Without a GUI: Trapped in the 50's.

Any decent IDE or editor will tell you where a function/variable is from. Even the original VI (<64kb) will do this with CTags. There is just no excuse for using crappy tools. Good ones are given away for free!.

Tim Williscroft
+3  A: 

There is a good technical reason to prefer to use or avoid this - the two are not always equivalent.

Consider the following code:

int f();

template <typename T>
struct A
{
  int f();
};

template <typename T>
struct B : A<T>
{
  int g()
  {
    return f();
    return this->f();
  }
};

Now, there are two f() calls in B<T>::g(). One would expect it to call A<T>::f(), but only the second one will. The first will call ::f(). The reason behind this is that because A<T> is dependent on T, the lookup does not normally find it. this, by being a pointer to B<T>, is also dependent on T however, so if you use it, the lookup will be delayed until after B<T> is instantiated.

Note that this behavior may not be present on some compilers (specifically, MSVC) which do not implement two-phase name lookup, but nonetheless it is the correct behavior.

coppro
I think of this as one more way that C++ is broken... also, note that the second call to f will never get called because the 1st is a return statement B-)
Brian Postow
+9  A: 

I'd never seen this style until I joined my current employer. The first time I saw it I thought "this idiot has no idea and Java/OO languages generally are not his strong suit", but it turns out that it's a regularly-occurring affliction here and is mandatory style on a couple of projects, although these projects also use the

if (0 == someValue)
{
    ....
}

approach to doing conditionals, i.e. placing the constant first in the test so that you don't run the risk of writing

if (someValue = 0)

by accident - a common problem for C coders who ignore their compiler warnings. Thing is, in Java the above is simply invalid code and will be chucked out by the compiler, so they're actually making their code less intuitive for no benefit whatsoever.

For me, therefore, far from showing "the author is coding with a dedicated thought process", these things strike me as more likely to come from the kind of person who just sticks to the rules someone else told them once without questioning them or knowing the reasons for the rules in the first place (and therefore where the rules shouldn't apply).

The reasons I've heard mainly boil down to "it's best practice" usually citing Josh Bloch's Effective Java which has a huge influence here. In fact, however, Bloch doesn't even use it where even I think he probably should have to aid readability! Once again, it seems to be more the kind of thing being done by people who are told to do it and don't know why!

Personally, I'm inclined to agree more with what Bruce Eckel says in Thinking in Java (3rd and 4th editions):


'Some people will obsessively put this in front of every method call and field reference, arguing that it makes it "clearer and more explicit." Don't do it. There's a reason that we use high-level languages: They do things for us. If you put this in when it's not necessary, you will confuse and annoy everyone who reads your code, since all the rest of the code they've read won't use this everywhere. People expect this to be used only when it is necessary. Following a consistent and straightforward coding style saves time and money.'


footnote, p169, Thinking in Java, 4th edition

Quite. Less is more, people.

raimesh
+1  A: 

I use this for at least two reasons:

Fallacies reasons

I like to have consistent code styles when coding in C++, C, Java, C# or JavaScript. I keep myself using the same coding style, mostly inspired from java, but inspired by the other languages.

I like also to keep a coherence inside my code in one language. I use typename for template type parameters, instead of class, and I never play mixer with the two. This means that I hate it when having to add this at one point, but avoid it altogether.

My code is rather verbous. My method names can be long (or not). But they always use full names, and never compacted names (i.e. getNumber(), not getNbr()).

These reasons are not good enough from a technical viewpoint, but still, this is my coding way, and even if they do no (much) good, they do no (much) evil. In fact, in the codebase I work on there are more than enough historical anti-patterns wrote by others to let them question my coding style.

By the time they'll learn writing "exception" or "class", I'll think about all this, again...

Real reasons

While I appreciate the work of the compiler, there are some ambiguities I'd like to make UN-ambiguities.

For example, I (almost) never use using namespace MyNamespace. I either use the full namespace, or use a three-letters alias. I don't like ambiguities, and don't like it when the compiler suddenly tells me there are too functions "print" colliding together.

This is the reason I prefix Win32 functions by the global namespace, i.e. always write ::GetLastError() instead of GetLastError().

This goes the same way for this. When I use this, I consciously restrict the freedom of the compiler to search for an alternative symbol if it did not find the real one. This means methods, as well as member variables.

This could apparently be used as an argument against method overloading, perhaps. But this would only be apparent. If I write overloaded methods, I want the compiler to resolve the ambiguity at compile time. If a do not write the this keyword, it's not because I want to compiler to use another symbol than the one I had in mind (like a function instead of a method, or whatever).

My Conclusion?

All in all, this problem is mostly of style, and with genuine technical reasons. I won't want the death of someone not writing this.

As for Bruce Eckel's quote from his "Thinking Java"... I was not really impressed by the biased comparisons Java/C++ he keeps doing in his book (and the absence of comparison with C#, strangely), so his personal viewpoint about this, done in a footnote... Well...

paercebal
A: 

less readable unless of course your students are still on green screen terminals like the students here... the elite have syntax highighting.

i just heard a rumour also that they have refactoring tools too, which means you don't need "this." for search and replace, and they can remove those pesky redundant thisses with a single keypress. apparently these tools can even split up methods so they're nice and short like they should have been to begin with, most of the time, and then it's obvious even to a green-screener which vars are fields.

Partly Cloudy