Saturday, 1 June 2019

Disadvantages of Autoboxing


Autoboxing is a feature to convert primitive types to their wrapper types.

Below table summarizes the primitive types and their wrapper types.

Primitive Type
Wrapper Type
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean

App.java
package com.sample.app;

public class App {
 public static void main(String args[]) {
  byte b = 10;
  short s = 11;
  int i = 12;
  long l = 13;

  float f = 1.23f;
  double d = 1.23;

  char c = 'x';
  boolean bool = true;

  Byte bWrapper = b;
  Short sWrapper = s;
  Integer iWrapper = i;
  Long lWrapper = l;

  Float fWrapper = f;
  Double dWrapper = d;

  Character cWrapper = c;
  Boolean boolWrapper = bool;

  System.out.println("b : " + b + " , bWrapper : " + bWrapper);
  System.out.println("s : " + s + " , sWrapper : " + sWrapper);
  System.out.println("i : " + i + " , iWrapper : " + iWrapper);
  System.out.println("l : " + l + " , lWrapper : " + lWrapper);
  System.out.println("f : " + f + " , fWrapper : " + fWrapper);
  System.out.println("d : " + d + " , dWrapper : " + dWrapper);
  System.out.println("c : " + c + " , cWrapper : " + cWrapper);
  System.out.println("bool : " + bool + " , boolWrapper : " + boolWrapper);
 }
}


Output

b : 10 , bWrapper : 10
s : 11 , sWrapper : 11
i : 12 , iWrapper : 12
l : 13 , lWrapper : 13
f : 1.23 , fWrapper : 1.23
d : 1.23 , dWrapper : 1.23
c : x , cWrapper : x
bool : true , boolWrapper : true

Tricky problems to keep an eye while working with Autoboxing
a. Lead to unexpected behaviour and difficult to track the errors
public static boolean equals(Long longObj, Object obj) {
         System.out.println("obj class : " + obj.getClass());
         if (obj instanceof Long) {
                  return longObj.longValue() == ((Long) obj).longValue();
         }
         return false;
}

Above method return true, if you call equals(longObject, 10l), but false if you call ‘equals(longObject, 10)’.

It is because ‘10’ is autoboxed to Integer, where as 10l is autoboxed to Long.


App.java

package com.sample.app;

public class App {
 public static boolean equals(Long longObj, Object obj) {
  //System.out.println("obj class : " + obj.getClass());
  if (obj instanceof Long) {
   return longObj.longValue() == ((Long) obj).longValue();
  }
  return false;
 }
 

 public static void main(String args[]) {
  Long longObject = 10l;

  System.out.println("equals(longObject, 10l) : " + equals(longObject, 10l));
  System.out.println("equals(longObject, 10) : " + equals(longObject, 10));

 }
}

Output
equals(longObject, 10l) : true
equals(longObject, 10) : false

Unknows memory consumption
Integer i1 = 1000;

for(int i = 1000; i < 2000; i++) {
         i1++;
}

What exactly i1++ do?
When you run above snippet, java creates 1000 new integer objects.

When Java encounter ‘i1++’ statement, it converts i1 to an integer and increments the value of i1 by 1 and converts it back to new Integer object by calling ‘valueOf’ method.

Definition of ‘valueOf’ method looks like below.
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

If you would like to know about IntegerCache, I would recommend you to go through my below post.

Chance of getting NullPointerException
If wrapper object is null and java tries to unbox it, then application throws NullPointerException.


App.java

package com.sample.app;

public class App {

 private static int sum(int a, int b) {
  return a + b;
 }

 public static void main(String args[]) {
  Integer a = null;
  int b = 10;

  int result = sum(a, b);
  System.out.println(result);
 }
}

Output
Exception in thread "main" java.lang.NullPointerException
         at com.sample.app.App.main(App.java:15)

Method overloading problem
Suppose I defined two methods like below.

private static void printEle(long l) {
         System.out.println("Primitive Method called");
}

private static void printEle(Long l) {
         System.out.println("Wrapper Method called");
}

First method takes a primitive long type and second one takes Wrapper type Long as arguments.

printEle(new Integer(10));
When you call printEle method by passing Integer object as argument, since there is no direction conversion between Integer and Long possible, Java converts Integer to primitive type long, "Primitive Method called" is printed to the console.


App.java

package com.sample.app;

public class App {

 private static void printEle(long l) {
  System.out.println("Primitive Method called");
 }

 private static void printEle(Long l) {
  System.out.println("Wrapper Method called");
 }

 public static void main(String args[]) {
  printEle(new Integer(10));
 }
}

Output
Primitive Method called


You may like


No comments:

Post a Comment