Force Java compiler to assume that all variables are final - java

Is it possible -- via a compiler switch or a commonly used tool (which I do not know) -- to break a compilation if a variable is reassigned when not marked as a mutable keyword (which is not present in Java yet)?
Example:
Contract a; // compile error
Contract b = getContract(id); // ok
b.doSomething(); // ok
b = getContract(otherId); // compile error
mutable int i = 1;
i++; // ok
I know that there are languages are like this, but being forced to code java in a company, using such a tool is the only choice.
Greetings,
JG.

Take a look at CheckStyle static code analysis tool. You can also integrate it to your IDE.
FinalLocalVariable check looks like your case:
Checks that local variables that never have their values changed are
declared final. The check can be configured to also check that
unchanged parameters are declared final.
Also there is PMD source code analyzer. But I've never used it so cannot suggest anything.

No, you can't force a Java compiler to do that. And you can't put non-Java keywords (like mutable) into Java source code. No compliant Java compiler will allow either of these.
You could possibly use a custom annotation to "declare" mutable local variables, and use a static analyser to detect assignments to locals without the annotation.
There may even be existing analyser tools, annotations, etc that will do this for you, though I am not aware of a tool that exactly fits the bill.
(The FinalLocalVariable check for CheckStyle doesn't do exactly what you want. It will tell you where to add final to declarations, but that isn't what you are asking for ... I think. You want variables to be treated as final even if they are not explicitly declared as such.)
But in my opinion, it would be a bad idea to do this.
Your employer has made a decision (right or wrong) that Java is the only language you can use. One of the reasons for this will ensuring that the code that you develop can be maintained and enhanced by Java programmers. By using unusual notations so that you can write zero-assignment code, you are undermining company policy.
At best, you won't make yourself popular with your coworkers by doing this.

Related

Any risk using a single dollar sign `$` as a java class name?

Originally I was using the underscore _ as a class name. The new Java8 compiler complains that it "might not be supported after Java SE 8". I changed that to $, and there is no warning any more. However I remember that $ is used by Java to indicate an inner/embedded class in the byte code. I am wondering if there is any risk to use a dollar sign $ as a class name
Some background to this question. What I want to do is to overcome the fact that Java doesn't support pure function, and the _ or $ is to put an namespace to encapsulate some very generic concept (classes/static methods). and neither do I have a good name for this, nor do I want the lib user type too many things to reference that namespace. Here is the code showing what I am doing under the way: https://github.com/greenlaw110/java-tool/blob/master/src/main/java/org/osgl/_.java
It is bad style, and potentially risky to use $ in any identifier in Java. The reason it is risky is that the $ character is reserved for the use of the Java toolchain and third-party language tools.
It is used by Java compilers in "internal" class names for inner and nested classes.
It is used by Java compilers in the names of synthetic attributes.
It could be used by third-party code generators (e.g. annotation processors) for various purposes.
It could be used by other languages that target the JVM platform, and that might need to co-exist with your code.
You probably won't have technical issues with a plain $ classname at the moment (at least with respect to the standard Java toolchain). But there's always the possibility that this will change in the future:
They have (effectively) reserved the right to change this1.
There is a precedent for doing this in the _ example.
If you really, really need a one-character classname, it would be better to play it safe and use F or Z or something else that isn't reserved.
But to be honest, I think you'd be better off trying to implement (or just use) a real functional language than trying to shoe-horn a functional programming "system" into Java. Or maybe, just switch to Java 8 ahead of its official release. 'Cos I for one would refuse to read / maintain a Java codebase that looked like jquery.
I don't mean to create a functional lib for Java, just want to create a lib to maintain some common utilities I used. Again, I am a advocate of minimalism and feel suck with things like apache commons. The functional stuff is added to help me easier to manipulate collection(s).
If it is your code, you can do what you like. Make your own decisions. Act on your opinions. Be a "risk taker" ... :-). (Our advice on $, etcetera ... is moot.)
But if you are writing this code for a client or employer, or with the intention of creating a (viable) open source product, then you need to take account of other people's opinion. For example, your boss needs to have an informed opinion on how maintainable your code will be if you find a better paying job somewhere else. In general, will the next guy be able to figure it out, keep your code, fresh, etc ... or will it be consigned to the dustbin?
1 - JLS §3.8 states "The $ character should be used only in mechanically generated source code". That is saying "use it at your peril". The assumption is that folks who build their own source code generators can change them if the standard toolchain uses a bare $ ... but it is harder to change lots of hand written code, and that would be an impediment to upgrading.
Huh, you're right, using a $ in a classname works. Eclipse complains that it is against convention, but, if you are sure, you can do it.
The problem (conventionally) with using a $ is that the $ is used in the class hierarchy to indicate nested classes.... for example, the file A.java containing:
class A {
class SubA {
}
}
would get compiled to two files:
A.class
A$SubA.class
Which is why, even though $ works, it is ill advised because parsing the jars may be more difficult... and you run the risk of colliding two classes and causing other issues
EDIT, I have just done a test with the following two Java files (in the default package)
public class A {
private static final class SubA {
public String toString() {
return "I am initializing Nested SUBA";
}
}
private static final SubA sub = new SubA();
public A() {
System.out.println("What is " + sub.toString());
}
}
public class A$SubA {
#Override
public String toString() {
return "I am A$SubA";
}
}
public class MyMain {
public static void main(String[] args) {
System.out.println(new A());
System.out.println(new A$SubA());
}
}
And the code will not compile.....
Two problems, type A$SubA is already defined, and can't reference a nested class A$SubA by it's binary name.
Yes, to be pedantic about answering your question there is a risk. As some other folks have mentioned, it violates java naming conventions. So the risk is that with future versions of the JDK this may cause problems. But beyond that, and some issues if you try to use nested classes you should be fine.
I think you're trying to avoid ugly names like Util.andThen. Consider using static imports. That lets you import all the methods in the header import static org.ogsl.Util.*, so then you can simply use you andThen without any prefix at all.
The Selenide project does it. Just look at the top of this documentation:
https://selenide.org/documentation.html
Maybe it is a more acceptable thing to do only in test code.
API ref:
https://selenide.org/javadoc/current/com/codeborne/selenide/Selenide.html

Can I always use the Reflection API if the code is going to be obfuscated?

I found that there seem to be 2 general solutions:
don't obfuscate what is referred to through the reflection API [Retroguard, Jobfuscate]
replace Strings in reflection API invocations with the obfuscated name.
Those solutions work only for calls within the same project - client code (in another project) may not use the reflection API to access non-public API methods.
In the case of 2 it also only works when the Reflection API is used with Strings known at compile-time (private methods testing?). In those cases dp4j also offers a solution injecting the reflection code after obfuscation.
Reading Proguard FAQ I wondered if 2 otherwise always worked when it says:
ProGuard automatically handles
constructs like
Class.forName("SomeClass") and
SomeClass.class. The referenced
classes are preserved in the shrinking
phase, and the string arguments are
properly replaced in the obfuscation
phase.
With variable string arguments, it's generally not possible to determine
their possible values.
Q: what does the statement in bold mean? Any examples?
With variable string arguments, it's generally not possible to determine their possible values.
public Class loadIt(String clsName) throws ClassNotFoundException {
return Class.forName(clsName);
}
basically if you pass a non-constant string to Class.forName, there's generally no way for proguard or any obfuscation tool to figure out what class you are talking about, and thus can't automatically adjust the code for you.
The Zelix KlassMaster Java obfuscator can automatically handle all Reflection API calls. It has a function called AutoReflection which uses an "encrypted old name" to "obfuscated name" lookup table.
However, it again can only work for calls within the same obfuscated project.
See http://www.zelix.com/klassmaster/docs/tutorials/autoReflectionTutorial.html.
It means that this:
String className;
if (Math.random() <= 0.5) className = "ca.simpatico.Foo";
else className = "ca.simpatico.Bar";
Class cl = Class.forName(className);
Won't work after obfuscation. ProGuard doesn't do a deep enough dataflow analysis to see that the class name which gets loaded came from those two string literals.
Really, your only plausible option is to decide which classes, interfaces, and methods should be accessible through reflection, and then not obfuscate those. You're effectively defining a strange kind of API to clients - one which will only be accessed reflectively.

why MyClass.class exists in java and MyField.field isn't?

Let's say I have:
class A {
Integer b;
void c() {}
}
Why does Java have this syntax: A.class, and doesn't have a syntax like this: b.field, c.method?
Is there any use that is so common for class literals?
The A.class syntax looks like a field access, but in fact it is a result of a special syntax rule in a context where normal field access is simply not allowed; i.e. where A is a class name.
Here is what the grammar in the JLS says:
Primary:
ParExpression
NonWildcardTypeArguments (
ExplicitGenericInvocationSuffix | this Arguments)
this [Arguments]
super SuperSuffix
Literal
new Creator
Identifier { . Identifier }[ IdentifierSuffix]
BasicType {[]} .class
void.class
Note that there is no equivalent syntax for field or method.
(Aside: The grammar allows b.field, but the JLS states that b.field means the contents of a field named "field" ... and it is a compilation error if no such field exists. Ditto for c.method, with the addition that a field c must exist. So neither of these constructs mean what you want them to mean ... )
Why does this limitation exist? Well, I guess because the Java language designers did not see the need to clutter up the language syntax / semantics to support convenient access to the Field and Method objects. (See * below for some of the problems of changing Java to allow what you want.)
Java reflection is not designed to be easy to use. In Java, it is best practice use static typing where possible. It is more efficient, and less fragile. Limit your use of reflection to the few cases where static typing simply won't work.
This may irk you if you are used to programming to a language where everything is dynamic. But you are better off not fighting it.
Is there any use that is so common for class literals?
I guess, the main reason they supported this for classes is that it avoids programs calling Class.forName("some horrible string") each time you need to do something reflectively. You could call it a compromise / small concession to usability for reflection.
I guess the other reason is that the <type>.class syntax didn't break anything, because class was already a keyword. (IIRC, the syntax was added in Java 1.1.)
* If the language designers tried to retrofit support for this kind of thing there would be all sorts of problems:
The changes would introduce ambiguities into the language, making compilation and other parser-dependent tasks harder.
The changes would undoubtedly break existing code, whether or not method and field were turned into keywords.
You cannot treat b.field as an implicit object attribute, because it doesn't apply to objects. Rather b.field would need to apply to field / attribute identifiers. But unless we make field a reserved word, we have the anomalous situation that you can create a field called field but you cannot refer to it in Java sourcecode.
For c.method, there is the problem that there can be multiple visible methods called c. A second issue that if there is a field called c and a method called c, then c.method could be a reference to an field called method on the object referred to by the c field.
I take it you want this info for logging and such. It is most unfortunate that such information is not available although the compiler has full access to such information.
One with a little creativity you can get the information using reflection. I can't provide any examples for asthere are little requirements to follow and I'm not in the mood to completely waste my time :)
I'm not sure if I fully understand your question. You are being unclear in what you mean by A.class syntax. You can use the reflections API to get the class from a given object by:
A a = new A()
Class c = a.getClass()
or
Class c = A.class;
Then do some things using c.
The reflections API is mostly used for debugging tools, since Java has support for polymorphism, you can always know the actual Class of an object at runtime, so the reflections API was developed to help debug problems (sub-class given, when super-class behavior is expected, etc.).
The reason there is no b.field or c.method, is because they have no meaning and no functional purpose in Java. You cannot create a reference to a method, and a field cannot change its type at runtime, these things are set at compile-time. Java is a very rigid language, without much in the way of runtime-flexibility (unless you use dynamic class loading, but even then you need some information on the loaded objects). If you have come from a flexible language like Ruby or Javascript, then you might find Java a little controlling for your tastes.
However, having the compiler help you figure our potential problems in your code is very helpful.
In java, Not everything is an object.
You can have
A a = new A()
Class cls = a.getClass()
or directly from the class
A.class
With this you get the object for the class.
With reflection you can get methods and fields but this gets complicated. Since not everything is an object. This is not a language like Scala or Ruby where everything is an object.
Reflection tutorial : http://download.oracle.com/javase/tutorial/reflect/index.html
BTW: You did not specify the public/private/protected , so by default your things are declared package private. This is package level protected access http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

How important are naming conventions for getters in Java?

I’m a huge believer in consistency, and hence conventions.
However, I’m currently developing a framework in Java where these conventions (specifically the get/set prefix convention) seem to get in the way of readability. For example, some classes will have id and name properties and using o.getId() instead of o.id() seems utterly pointless for a number of reasons:
The classes are immutable so there will (generally) be no corresponding setter,
there is no chance of confusion,
the get in this case conveys no additional semantics, and
I use this get-less naming schema quite consistently throughout the library.
I am getting some reassurance from the Java Collection classes (and other classes from the Java Platform library) which also violate JavaBean conventions (e.g. they use size instead of getSize etc.).
To get this concern out of the way: the component will never be used as a JavaBean since they cannot be meaningfully used that way.
On the other hand, I am not a seasoned Java user and I don’t know what other Java developers expect of a library. Can I follow the example of the Java Platform classes in this or is it considered bad style? Is the violation of the get/set convention in Java library classes deemed a mistake in retrospect? Or is it completely normal to ignore the JavaBean conventions when not applicable?
(The Sun code conventions for Java don’t mention this at all.)
If you follow the appropriate naming conventions, then 3rd-party tools can easily integrate with and use your library. They will expect getX(), isX() etc. and try to find these through reflection.
Although you say that these won't be exposed as JavaBeans currently, I would still follow the conventions. Who knows what you may want to do further down the line ? Or perhaps at a later stage you'll want to extract an interface to this object and create a proxy that can be accessed via other tools ?
I actually hate this convention. I would be very happen if it was replaced by a real java tool that would provide the accessor/modifier methods.
But I do follow this convention in all my code. We don't program alone, and even if the whole team agrees on a special convention right now, you can be assured that future newcomers, or a future team that will maintain your project, will have a hard time at the beginning... I believe the inconvenience for get/set is not as big as the inconvenience from being non-standard.
I would like to raise another concern : often, java software uses too many accessors and modifiers (get/set). We should apply much more the "Tell, don't ask" advice. For example, replace the getters on B by a "real" method:
class A {
B b;
String c;
void a() {
String c = b.getC();
String d = b.getD();
// algorithm with b, c, d
}
}
by
class A {
B b;
String c;
void a() {
b.a(c); // Class B has the algorithm.
}
}
Many good properties are obtained by this refactor:
B can be made immutable (excellent for thread-safe)
Subclasses of B can modify the computation, so B might not require another property for that purpose.
The implementation is simpler in B it would have been in A, because you don't have to use the getter and external access to the data, you are inside B and can take advantage of implementation details (checking for errors, special cases, using cached values...).
Being located in B to which it has more coupling (two properties instead of one for A), chances are that refactoring A will not impact the algorithm. For a B refactoring, it may be an opportunity to improve the algorithm. So maintenance is less.
The violation of the get/set convention in the Java library classes is most certainly a mistake. I'd actually recommend that you follow the convention, to avoid the complexity of knowing why/when the convention isn't followed.
Josh Bloch actually sides with you in this matter in Effective Java, where he advocates the get-less variant for things which aren't meant to be used as beans, for readability's sake. Of course, not everyone agrees with Bloch, but it shows there are cases for and against dumping the get. (I think it's easier to read, and so if YAGNI, ditch the get.)
Concerning the size() method from the collections framework; it seems unlikely it's just a "bad" legacy name when you look at, say, the more recent Enum class which has name() and ordinal(). (Which probably can be explained by Bloch being one of Enum's two attributed authors. ☺)
The get-less schema is used in a language like scala (and other languages), with the Uniform Access Principle:
Scala keeps field and method names in the same namespace, which means we can’t name the field count if a method is named count. Many languages, like Java, don’t have this restriction, because they keep field and method names in separate namespaces.
Since Java is not meant to offer UAP for "properties", it is best to refer to those properties with the get/set conventions.
UAP means:
Foo.bar and Foo.bar() are the same and refer to reading property, or to a read method for the property.
Foo.bar = 5 and Foo.bar(5) are the same and refer to setting the property, or to a write method for the property.
In Java, you cannot achieve UAP because Foo.bar and Foo.bar() are in two different namespaces.
That means to access the read method, you will have to call Foo.bar(), which is no different than calling any other method.
So this get-set convention can help to differentiate that call from the others (not related to properties), since "All services (here "just reading/setting a value, or computing it") offered by a module cannot be available through a uniform notation".
It is not mandatory, but is a way to recognize a service related to get/set or compute a property value, from the other services.
If UAP were available in Java, that convention would not be needed at all.
Note: the size() instead of getSize() is probably a legacy bad naming preserved for the sake of Java's mantra is 'Backwardly compatible: always'.
Consider this: Lots of frameworks can be told to reference a property in object's field such as "name". Under the hood the framework understands to first turn "name" into "setName", figure out from its singular parameter what is the return type and then form either "getName" or "isName".
If you don't provide such well-documented, sensible accessor/mutator mechanism, your framework/library just won't work with the majority of other libraries/frameworks out there.

Is writing "this." before instance variable and methods good or bad style?

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:
Makes code more readable — Easier to distinguish fields from local variables.
Makes it easier to distinguish standard calls from static calls (especially in Java)
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?
Note: I turned it into a CW since there really isn't a correct answer.
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"
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:
What kind of prefix do you use for member variables?
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.
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!.
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.
More readable, I think. I do it your way for exactly the same reasons.
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.
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.
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.
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.
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.
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...
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.
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.
"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.
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.
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?
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.
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;
}
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.

Categories

Resources