| Start |
|---|
| Pitfall: using == to compare primitive wrappers objects such as Integer (This pitfall applies equally to all primitive wrapper types, but we will illustrate it for When working with Here we created two This behavior changes when we choose different values: In this case, only the The reason for this difference in behavior is, that the JVM maintains a cache of Thus, in the first example the The |
| Pitfall: using == to compare strings A common mistake for Java beginners is to use the The above program is supposed to test the first command line argument and print different messages when it and isn't the word "hello". But the problem is that it won't work. That program will output "Are you feeling grumpy today?" no matter what the first command line argument is. In this particular case the When you use But it actually gets worse. The problem is that Interestingly, this will print "same", even though we are testing the strings the wrong way. Why is that? Because the Java Language Specification (Section 3.10.5: String Literals) (opens new window) stipulates that any two string >>literals<< consisting of the same characters will actually be represented by the same Java object. Hence, the To add to the confusion, the Java Language Specification also stipulates that when you have a compile-time constant expression that concatenates two string literals, that is equivalent to a single literal. Thus: This will output "1. same" and "2. different". In the first case, the In summary, using |
| Pitfall: forgetting to free resources Every time a program opens a resource, such as a file or network connection, it is important to free the resource once you are done using it. Similar caution should be taken if any exception were to be thrown during operations on such resources. One could argue that the Since Java 7 there is a really useful and neat statement introduced in Java 7 particularly for this case, called try-with-resources: The try-with-resources statement can be used with any object that implements the In cases where the resource has already been opened but should be safely closed after use, one can assign it to a local variable inside the try-with-resources The local resource variable created in the try-with-resources constructor is effectively final. |
| Pitfall: testing a file before attempting to open it. Some people recommend that you should apply various tests to a file before attempting to open it either to provide better diagnostics or avoid dealing with exceptions. For example, this method attempts to check if You might use the above method like this: The first problem is in the signature for The second problem is that checks performed by The third problem is that the tests are inefficient. For example, the In short, methods like If you wanted to distinguish IO errors thrown while opening and reading, you could use a nested try / catch. If you wanted to produce better diagnostics for open failures, you could perform the |
| Pitfall: thinking of variables as objects No Java variable represents an object. Neither does any Java array contain objects. If you mistakenly think of variables as objects, the actual behavior of the Java language will surprise you. Variables are not objects in either case, and they don't contain objects in either case. They may contain references to objects, but that is saying something different. Example classThe examples that follow use this class, which represents a point in 2D space. An instance of this class is an object that has two fields We can have many instances of the Multiple variables can point to the same objectIn the above, we have declared three variables If you (incorrectly) think of these variables as being objects, then you are likely to misread the statements as saying:
From that, you are likely to infer we have three independent objects in the three variables. In fact there are only two objects created by the above. The variables We can demonstrate this. Assuming the variable declarations as above: This will output the following: We assigned a new value to If a variable was an object, then the assignment The equality operator does NOT test that two objects are equalApplying the equality ( This will print "here is there", but it won't print "here is elsewhere". (The references in By contrast, if we call the This will print both messages. In particular, Method calls do NOT pass objects at allJava method calls use pass by value1 to pass arguments and return a result. When you pass a reference value to a method, you're actually passing a reference to an object by value, which means that it is creating a copy of the object reference. As long as both object references are still pointing to the same object, you can modify that object from either reference, and this is what causes confusion for some. However, you are not passing an object by reference2. The distinction is that if the object reference copy is modified to point to another object, the original object reference will still point to the original object. Neither are you passing a copy of the object. 1 - In languages like Python and Ruby, the term "pass by sharing" is preferred for "pass by value" of an object / reference. 2 - The term "pass by reference" or "call by reference" has a very specific meaning in programming language terminology. In effect, it means that you pass the address of a variable or an array element, so that when the called method assigns a new value to the formal argument, it changes the value in the original variable. Java does not support this. For a more fulsome description of different mechanisms for passing parameters, please refer to https://en.wikipedia.org/wiki/Evaluation_strategy (opens new window). |
| Pitfall: memory leaks Java manages memory automatically. You are not required to free memory manually. An object's memory on the heap may be freed by a garbage collector when the object is no longer reachable by a live thread. However, you can prevent memory from being freed, by allowing objects to be reachable that are no longer needed. Whether you call this a memory leak or memory packratting, the result is the same -- an unnecessary increase in allocated memory. Memory leaks in Java can happen in various ways, but the most common reason is everlasting object references, because the garbage collector can’t remove objects from the heap while there are still references to them. Static fields One can create such a reference by defining class with a Classloader leak By far, though, the most insidious type of memory leak is the classloader leak (opens new window). A classloader holds a reference to every class it has loaded, and every class holds a reference to its classloader. Every object holds a reference to its class as well. Therefore, if even a single object of a class loaded by a classloader is not garbage, not a single class that that classloader has loaded can be collected. Since each class also refers to its static fields, they cannot be collected either. Accumulation leak The accumulation leak example could look like the following: This example creates two scheduled tasks. The first task takes the last number from a deque called If the code is executed, you’ll see that the size of the deque is permanently increasing. This will eventually cause the deque to be filled with objects that consume all available heap memory. To prevent this while preserving the semantics of this program, we can use a different method for taking numbers from the deque: |
| Pitfall: Not understanding that String is an immutable class New Java programmers often forget, or fail to fully comprehend, that the Java The above code is supposed to print command line arguments in upper case. Unfortunately, it does not work, the case of the arguments is not changed. The problem is this statement: You might think that calling In reality, the So in order to use this method effectively, you need to use the object returned by the method call; for example: In fact, the "strings never change" rule applies to all |
| Pitfall: combining assignment and side-effects Occasionally we see StackOverflow Java questions (and C or C++ questions) that ask what something like this: evaluates to ... for some known initial states of Generally speaking:
Such examples are often used in exams or job interviews as an attempt to see if the student or interviewee understands how expression evaluation really works in the Java programming language. This is arguably legitimate as a "test of knowledge", but that does not mean that you should ever do this in a real program. To illustrate, the following seemingly simple example has appeared a few times in StackOverflow questions (like this one (opens new window)). In some cases, it appears as a genuine mistake in someone's code. Most programmers (including Java experts) reading those statements quickly would say that it outputs However the real takeaway from this and similar examples is that any Java statement that both assigns to and side-effects the same variable is going to be at best hard to understand, and at worst downright misleading. You should avoid writing code like this. 1 - modulo potential issues with the Java Memory Model (opens new window) if the variables or objects are visible to other threads. |
Read Article
https://develop.horje.com/learn/1434/reference