Common Mistakes I found in the intern developers: Part 4

Dulaj Rajitha
5 min readApr 12, 2020
https://www.maxpixel.net/

If you are a fresh graduate who newly join to the java software industry, or an undergraduate who is joining a firm as an intern developer in java, this article contains the most common issues that you will probably do because of the lack of experience. It’s better to already getting know, what others who are the same as you have mistaken.

With the experience I got by working with software engineering interns, I noticed some of common mistakes and programming patterns.

Here I have listed down some of the common mistakes and bad practices which will be done by new software developers. Therefore this will help the new java developers to identify and correct their mistakes in the future.

This article is the fourth of the series.

  • equals operation

If you are are trying to check equality with a constant value, the proper way is constant.equals( variable ) way to avoid null point exceptions and avoid unnecessary null checks. Or else you can use null safe Objects.equlals( constant, variable ) method.

But it is very common to use variable.equals( constant ) method among new developers and this will lead to null point exceptions if the variable is null.

Example 1: using equals

//Not to do
if (input.equals("STRING")) {
System.out.println("match found");
}
//Option 1: constnat.equalsif ("STRING".equals(input)) {
System.out.println("match found");
}
//Option 2: Null safe equals
if (Objects.equals(input, "STRING")) {
System.out.println("match found");
}
  • not using isEmpty

As it seems most of the time, new programmers tend to use the collection’s size is not equal to zero, rather than using the inbuilt isEmpty method. Because the cost of calling the size method may differ based on the collection type.

//follow this way for collectionsif (input.isEmpty()){
System.out.println("empty found");
}
  • redundant conditions

Sometimes there are conditions that the value will be always true or false. Such cases can be simplified and it will reduce the code readability as well.

Such cases can be identified inside if conditions as well as in nested conditions.

Example 2: Redundant condition

private static <E> void doSomething(List<E> input) {

if (input.isEmpty()) {
//this condition is redundant since if the input is null, it cannot come inside this if block
if (input != null) {
// doing something
} else {
// do something else
}
}
}
  • mergeable conditions

There are scenarios that, some nested if conditions can be merged into a single condition.

  • not using the constant variables

When something is repeated over multiple occasions, we can introduce such into variables.

If something is repeated inside a method multiple times, we can introduce it to a local variable.

something is repeated over multiple methods in a same class, we can have a private constant in the class and reuse that.

If something is repeated over multiple classes, we can introduce that into a public constant and reuse it over the classes.

But rarely see such use in new programmers.

  • misuse of class variables and local variables

There are occasions that class variables are used in the places that local variables can be used and vise versa.

  • cognitive complexity

One of the major qualities of good code is readability and understandability. But there are methods that have a very high level of complexity. Because some methods do not serve a unit functionality, consists of multiple validations and consists of application flows and conditions inside the same method body, a method can become very complex. Then the readability of the method will become more and more harder for another person.

Such methods can be break into multiple methods and there are some conditions that can be simplified.

  • methods with a large number of parameters

If a method has a large number of input parameters, when calling the method it will be hard and less readable. Readability will more decreased if that method is overloaded by other methods.

private void doSomething(String name, String middleName, String lastName, Integer age, Double height, Double weight, Collection<String> interests, Collection<String> hobbies, String otherParam) {
//doing something
}

The proper way to handle such incidents is to use a class with the combination of those parameters as input.

//  Created a class Person and included person related parameters to the person
private void doSomething(Person person,String otherParam) {
//doing something
}
  • Exception handling

Under Exception handling, the following errors are very common

  • not catching specific exceptions

There are occasions that different exceptions should be handled in different ways. Therefore catching the Exception is not a good practice.

The proper way is to catch individual exceptions separately using multi catch statements and handle separately. Sometimes if some exceptions should be handled in same way, then they can be combined into a single catch block.

  • Once the exception is caught, it should log or return

Once an exception is caught, if we are not logging the exception or not throwing a different exception (or the same), then later debugging the application and identifying the root cause will be externally hard.

Because something has gone wrong, but it has not logged or not thrown to handled in a different location and based on the output we cannot conclude anyting.

  • variable scope

Once we declare variables, we should have a proper understanding of the scope. If we have public class variables, we should know that they will be overridden in the child classes. If we have local variables, still within the loops and so on we can still adjust the proper scopes to adjust the redeclaration and re-initialization accordingly.

  • variable and method naming

Variable name should be provide the meaning of itself without an extra comments.

But there are numerous occasions that the variable and method names do not reflect the intention of itself.

Constant filed names are naming with all upper case as best practice for make the code more readable.

But sometimes that same conversation is used for local variables and non-constant variables by new developers which should be avoided.

  • boolean variable naming

Boolean variables and their getters can follow a specific naming compared with other variables.

Example: variable booleans getter shold start with is or has and not with the get. For example, variable for indicate something is initialized or not, name shold be like initialized. Then the getter shold be isInitialized().

  • No equal and hashcode methods in classes

In java equals method is defined for all of the classes by default. Once we do the object comparison, and if the equals method is not properly overridden, you may not get the expected results.

Also adding the same instance to a set or hash map supposed to replace the old instance. But if you missed the overriding of the hashcode method, the expected outcome is not guaranteed.

Therefore it a good practice for override the methods equals and hashCode for all of the non-utility classes (where object equality comparisons occur). Also, need to be mindful for nullable fields as well once overriding those methods.

Example 2: Class with equals and hashCode

private static class Person {
private String name;
private Double age;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return name.equals(person.name) &&
age.equals(person.age);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

Please leave a comment below if you have any questions or feedback.

If you like this post, follow me on Medium for more similar posts.

If you have any concerns or questions, please use the comment section below.

--

--