Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Warning About Overloading Methods in Java

DZone's Guide to

A Warning About Overloading Methods in Java

Autoboxing and method overloading can be useful when building a Java app. But sometimes these features can cause confusion, improper outputs, or errors, if not handled carefully.

· Java Zone
Free Resource

The single app analytics solutions to take your web and mobile apps to the next level.  Try today!  Brought to you in partnership with CA Technologies

Before Java 1.5, primitive types were completely different from reference types. The introduction of the autoboxing feature has made this difference dissapear after Java 1.5. But, it has brought many problems, also.

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class SetAndList{

	public static void main(String[] args) {
		Set<Integer> set = new TreeSet<Integer>();
		List<Integer> list = new ArrayList<Integer>();
		for (int i = -2; i < 3; i++) {
			set.add(i);
			list.add(i);
		}

		for (int i = 0; i < 3; i++) {
			set.remove(i);
			list.remove(i);
		}      
		System.out.println(set + " " + list);
	}
}

Many of us might think that the output of the above code would print:

[-2, -1] [-2, -1]

But unfortunately, the above code works in a different way, and actually produces the following output:

[-2, -1] [-1, 1]

We can explain the above situation with the careless usage of "autoboxing," which has entered our lives since Java 1.5, as well as "overloading" features.

With the line "set.remove(i)" in the above code, the "remove(E)" method is called. Here "E" is the element type of Set which is "Integer" and the int value is converted to "Integer" with the help of autoboxing feature. And as a result, the code removes positive values from the set as expected.

On the other hand, with the line "list.remove(i)" in the above code, the overloaded "remove(int i)" method is called. This method removes the value in the index "i". So, when the content of "list" is [ -2, -1, 0, 1, 2 ], the above code first removes the element in the index "0", then index "1" and then "2". At the end of the iteration, the content of the list remains [-1, 1].  In order to avoid confusion here, we should cast "i", in the line “list.remove(i)”, to "Integer" to make the rightly overloaded method called.

for (int i = 0; i < 3; i++) {
	set.remove(i);
	list.remove((Integer)i); // or list.remove(Integer.valueOf(i));
}

After this correction, the program output can be as expected.

[-2, -1] [-2, -1]

In the above code, the compiler confuses the overloaded "remove(E)" method of the List interface with overloaded "remove(int)" method of the same interface, because of the autoboxing feature. Hence, we can say, generic and autoboxing concepts has ruined the List interface since Java 1.5.

The lessons here can be summarized as follows:

  • Being able to overload our methods in our Java classes does not mean that we should overload them.

  • Generally, we should avoid overloading our methods, containing the same number of parameters. So we should give different and meaningful names to our methods. If we insist on overloading, then we must pay attention to make our methods show the same behavior.

In case they do not pay attention to the above items, we need to tell those coders new to overloaded methods to be careful while using methods. Otherwise, they may find it hard to understand why they do not work.

Resources

Polymorphism in Java – Method Overloading and Overriding

Efective Java 2nd Edition, J. Bloch

CA App Experience Analytics, a whole new level of visibility. Learn more. Brought to you in partnership with CA Technologies.

Topics:
java ,overloading ,autoboxing ,unboxing

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}