Sunday, March 25, 2018

Wrapper Classes in java


Wrapper Classes - Have you ever heard about them , if not , no issue you will get to know about it in this post.
There are some other post related to this , which can be helpful are
  1. Making Games With Java- Introduction
  2. Getting Everything you need for Java
  3. Introduction to Java Programming
  4. Basic data types and Variables in java
  5. Basic Data types and Variables in java - Continued...
  6. User Input using Scanner class in java
  7. Conditional Logic in java
  8. Loops in java
  9. Arrays in java


Wrapper Classes – why are they needed?

There is a class that has been dedicated to each of the 8 primitive data types in java. These primitive types are int, float, char, byte, long, short, boolean and double. The dedicated classes that “wrap” over these primitive types are called Wrapper Classes.
int num = 10; // primitive type
Integer num = new Integer(10); // wrapper class
The main purpose of these wrapper classes is:
  • To enable primitives to perform activities that can be performed by objects. For example being added to a collection
  • To be able to perform the different utility functions like converting to and from String objects, comparison on primitives

How can we create Wrapper Classes?

There are 2 ways of creating wrapper class instances in Java.

Using Constructor:

Constructors of the corresponding wrapper classes can be used to create instances with the help of the new keyword.
1)Accepts the primitive type as parameter
          Example: Integer num = new Integer (10);
2)Accepts string as parameter (except Character)
          Example: Integer num = new Integer ("10");

Using the valueOf method:

Another way of creating Wrapper class objects is by using the valueOf method.
There are 3 variants of this method.

1)Accepts primitive type as parameter
This statement will return an Integer object containing the value represented by the primitive type.
2)Accepts String parameter
This returns the Integer object for the String passed as parameter.
3)Accepts two parameters a String and radix.
The radix parameter will be used to determine the value of the Integer that is returned based on the String parameter passed.

The following example shows how both these ways can be used to create wrapper class instances:
public class WrapperExample {
    public static void main(String args[]) {
      Integer numint1 = new Integer (10);
      //or
      Integer numint2 = 10;
      Integer numStr = new Integer ("20");
   
      
      Integer withValueOf1 =Integer.valueOf(9);
      Integer withValueOf2 =Integer.valueOf("9");             
      Integer withValueOf3 = Integer.valueOf("444",16);

      System.out.println("numint1 = "+numint1); 
      System.out.println("numint2 = "+numint2);
      System.out.println("numStr = "+numStr);
      
      
      System.out.println("withValueOf1 = "+withValueOf1);
      System.out.println("withValueOf2 = "+withValueOf2);
      System.out.println("withValueOf3 = "+withValueOf3);
    }
}
In the above example, we can see the ways of creating wrapper class instances in java. When creating using constructors, one needs to be aware of the wrapper class name and the parameters it accepts.
As the wrapper classes come in last in the hierarchy, there is no subclass that one can get from them.


The constructor that accepts String parameters may throw NumberFormatexception if the string passed cannot be parsed into an Integer.

Using the valueOf() method seems more efficient as it returns cached objects which means that it is not always necessary to create a new object.

Autoboxing  and its advantages

  • When a primitive type is automatically converted to its corresponding wrapper object it is called autoboxing
  • This reduces code to convert from primitive types to Wrapper equivalents thus leading to cleaner code.
The following statement from the code above is the perfect example of autoboxing.
Integer numint2 = 10;
The above statement is an example of auto boxing.

Auto-boxing is done in the following cases:
  • When a primitive is passed as a parameter where an object of the corresponding wrapper class is expected.
  • When a primitive is assigned to a variable of the corresponding wrapper class as seen in the example above.
Following code snippet demonstrates auto-boxing for character:
//auto boxing
Character chWrapper = 'a';
// Auto-unboxing 
char ch = chWrapper;

Casting in Java – Implicit and explicit Casting

Taking an object of one type and converting it into another is the simplest way in which we can define Casting.
But obviously there are some rules that need to be followed. You cannot just take one variable and convert it into another type.

Implicit Casting:

  • Automatic type conversion or implicit casting happens if both the concerned types are compatible with each other and the target is larger/wider than the source.
  • No casting is specifically required in the case of implicit casting.
Examples:
short sh = 10;
 int num = sh;
 long l = num;
float fl = l;
double d = fl;
public class CastingExample {
    public static void main(String args[]) {
        short sh = 10;
        int num = sh;
        long l = num;
        float fl = l;
        double d = fl;

        System.out.println("Value of sh: " + sh);
        System.out.println("Value of num: " + num);
        System.out.println("Value of l: " + l);
        System.out.println("Value of fl: " + fl);
        System.out.println("Value of d: " + d);
    }
}
The implicit casting can be done in the following order only.
In inheritance too, implicit casting is present when we assign a child object to a parent class instance.
Example:
class Parent
{
 public void method()
 {
 // method body
 }
}
public class Child extends Parent
{
 public static void main(String args[])
 {
  Parent p = new Child();
  p.method();
 }
}

Explicit Casting:

If both the concerned types are compatible with each other but the source is larger/wider than the target then it is called explicit casting.
Here the conversion will happen the other way around.
To achieve narrowing, explicit casting needs to be done
double d = 75.0;
// Explicit casting 
float fl = (float) d;
long l = (long) fl;
int num  = (int) l;
short sh = (short) num;
public class CastingExample {
    public static void main(String args[]) {
        double d = 75.0;
// Explicit casting 
float fl = (float) d;
long l = (long) fl;
int num  = (int) l;
short sh = (short) num;
        System.out.println("Value of sh: " + sh);
        System.out.println("Value of num: " + num);
        System.out.println("Value of l: " + l);
        System.out.println("Value of fl: " + fl);
        System.out.println("Value of d: " + d);
    }
}
Similarly, in inheritance we can explicitly cast super type to a sub type.
Example
class Parent
{
 public void disp()
 {
  // method body
 }
}
public class Child extends Parent
{
 public void disp()
 {
  // method body
 }
 public static void main(String args[])
 {
  Parent p = new Child();
  p.disp();
  Child c = (Child)p;
  c.disp();
 }
}
Explicit casting to child class needs to be done to achieve this as seen in the code, Child c = (Child)p;


To summarise:
  • To be able to use the specific functionality of the target type, casting is done. When converting float to long I am able to store more data in it.
  • In the same way if we want to access some methods from a super class using the subclass variables we can use casting.
  • The object itself is not changed when you perform casting.
  • There has to be compatibility between the source and target types when casting. I cannot cast a variable of a subclass of A to a parent of B.
  • Upcasting or Implicit Casting can be automatic as it will never fail.
  • Downcasting or Explicit casting on the other hand may throw a ClassCastException in some cases. This is where the instanceof check can come in handy.
If you liked this post , please share it with your friends and colleagues. 

Thanks for reading 

0 comments:

Post a Comment