5 Most Common Java Pitfalls
Last Updated :
11 Mar, 2024
1. Not understanding that String is an immutable class:
The Java String class is immutable (Unmodifiable). This is because String objects are cached in a String pool. The object that a String is referencing to can change, but the String objects themselves cannot.
Example:
Java
public class Main {
public static void main(String[] args)
{
String str = "GeeksFor";
// A new string will be returned, but the actual String will remain the same
str.concat("Geeks");
// Prints initial value "GeeksFor"
System.out.println(str);
// Now we change the reference of "str" to point to the new String returned
str = str.concat("Geeks");
// Prints the new concatenated String
System.out.println(str);
}
}
Output : GeeksFor
GeeksForGeeks
2. Memory Leaks:
One of the core benefits of Java is the Java Garbage Collector, which manages the objects memory on the heap. Whenever an object is unreachable it is automatically freed.
However, a common slip for both new and experienced programmers is preventing the memory from being freed, by allowing objects to be reachable that are no longer in use. This can be a very big downside to a project since memory leaks block resources and degrades the application performance. It can even lead to java.lang.OutOfMemoryError.
Common Cases are:
- Static Fields Declaring a static field and forgetting to set it to null after its data is not longer needed
- Unclosed Streams The Java Virtual Machine allocates memory for every connection opened. Forgetting to close the connection consumes memory. Such connections can be: Input Streams, Database Connections, Sessions, and others.
- The finalize() method When we override the finalize() method, the object of that class is not any more directly garbage collected. The Garbage Collector is then waiting for finalization, which is happening at a later point in time.
3. Pre/Post Increment Operator and side-effects:
The evaluation order of operators in Java appear to be evaluated from left to right, the side effects can be seen instantly:
Java
public class Main {
public static void main(String[] args)
{
int num = 0;
/* First case */
// The increment operator happens after the value is pushed onto the stack and assigned
num = num++;
// Prints initial value
System.out.println(num);
/* Second case */
// Increment occurs first, and then it is pushed to the stack and assigned to num
num = ++num;
System.out.println(num);
}
}
Output : 0
1
The execution context of the first case is as follows:
- Store previous value of operand.
- Increment the value.
- Return the previous value
The execution context of the second case is as follows:
- Increment the value.
- Store value of operand (incremented)
- Return the value
4. Using the relational operator "==" for Objects comparison.
Many novice programmers try to use the "==" operator to compare objects and when the behavior of their code is not as expected they are confused. A thing to be aware of is that the relational operator "==" is making a reference comparison, it checks if both objects point to the same location in memory. Using the .equals() method will eliminate the problem since it compares the values inside the objects.
Java
public class Main {
public static void main(String[] args)
{
String s1 = new String("GeeksForGeeks");
String s2 = new String("GeeksForGeeks");
// Comparing using the relational operator
if (s1 == s2) { // false
System.out.println("Both objects point to the same memory location!");
}
// Comparing using the .equals()
if (s1.equals(s2)) { // true
System.out.println("The value inside the object instances match!");
}
// Declaring a string with a reference to s1
String s3 = s1;
if (s3 == s1) { // true
System.out.println("Both objects point to the same memory location!");
}
}
}
Output : The value inside the object instances match!
Both objects point to the same memory location!
Although sometimes the "==" operator will give the expected answer:
Java
public class Main {
public static void main(String[] args)
{
String s1 = "GeeksForGeeks";
String s2 = "GeeksForGeeks";
// Comparing using the relational operator
if (s1 == s2) { // true
System.out.println("The two strings are the same!");
}
else {
System.out.println("The two strings are the different!");
}
}
}
Output : The two strings are the same!
The reason is in the Java Language Specification String Literals: 'Literal strings within the same class in the same package represent references to the same String object'. The condition in the code is true because the literals are consisting of the same characters.
5. Using raw types
Before Java started using generic types, there have not been alternatives to raw types (types that are not parameterized). For backward compatibility reasons, it is still possible to define these:
Java
public class Main {
public static void main(String[] args)
{
// Defining a raw list, without specifying its type parameter
List geeksList = new ArrayList();
// Due to the unspecified type we can add any data type and the code will compile
geeksList.add(100);
geeksList.add(200);
geeksList.add("GeeksForGeeks");
// When the second element is reached the compiler will throw a runtime error
// because we are trying to cast a string to an integer
geeksList.forEach(k -> System.out.println((int)k * 2));
}
}
Output : 200
400
Exception in thread "main" java.lang.ClassCastException:
java.base/java.lang.String cannot be cast to java.base/java.lang.Integer
This issue can be prevented by defining the generic type of the List:
List geeksList = new ArrayList();
Now the code won't compile since we are trying to add a String type to a collection of Integer types. Generic Types are created for a reason and prevent programmers from nasty bugs and overheads.
Similar Reads
Top 10 Most Common Spring Framework Mistakes
"A person who never made a mistake never tried anything new" - Well said the thought of Albert Einstein. Human beings are prone to make mistakes. Be it technological aspect, mistakes are obvious. And when we talk about technology, frameworks play a very important role in building web applications. F
6 min read
10 Most Common Mistakes That Java Developers Make
If youâre working on any new programming language, there might be certain phases where you can get stuck. This eventually leads any developer to make minor-major errors and creates a roadblock towards their learning curve. Not to forget, as much as youâll be making mistakes, youâll achieve excellenc
9 min read
Java Methods Coding Practice Problems
Methods in Java help in structuring code by breaking it into reusable blocks. They improve readability, maintainability, and modularity in programming. This collection of Java method coding practice problems covers functions with return values, functions with arguments, and functions without argumen
1 min read
Scope of Variables in Java
The scope of variables is the part of the program where the variable is accessible. Like C/C++, in Java, all identifiers are lexically (or statically) scoped, i.e., scope of a variable can be determined at compile time and independent of the function call stack. In this article, we will learn about
7 min read
Java OOPs Coding Practice Problems
Object-Oriented Programming (OOP) is a core concept in Java that enables code modularity, reusability, and scalability. This collection of Java OOPs coding practice problems covers essential topics like class design, constructors, encapsulation, inheritance, and abstraction. Whether you are a beginn
2 min read
Access Modifiers in Java
In Java, access modifiers are essential tools that define how the members of a class, like variables, methods, and even the class itself can be accessed from other parts of our program. They are an important part of building secure and modular code when designing large applications. Understanding de
7 min read
How to Call a Method in Java?
In Java, calling a method helps us to reuse code and helps everything be organized. Java methods are just a block of code that does a specific task and gives us the result back. In this article, we are going to learn how to call different types of methods in Java with simple examples.What is a Metho
3 min read
Private and Final Methods in Java
Methods in Java play an important role in making the code more readable, support code reusability, and defining the behaviour of the objects. And we can also restrict the methods based on requirements using the keywords and modifiers such as final and private. These two have different, distinct purp
5 min read
Output of Java Programs | Set 33 (Collections)
Prerequisite: Java - Collections 1. What is the output of following Java Program? Java import java.util.ArrayList; class Demo { public void show() { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(4); list.add(7); list.add(1); for (int number : list) { System.out.print(numbe
3 min read
Output of Java Programs | Set 34 (Collections)
1. What is the Output of the following Java Program? Javaimport java.util.LinkedList; class Demo { public void show() { LinkedList<Integer> list = new LinkedList<Integer>(); list.add(1); list.add(4); list.add(7); list.add(5); for (int i = 0; i < list.size(); i++) { System.out.print(li
3 min read