5.Wrapper Class In JAVA

5.Wrapper Class In JAVA

What is a wrapper class?

Let's take an example.

Imagine you're running a bakery and you have some delicious cupcakes. Each cupcake is like a primitive data type – simple, tasty, and ready to be eaten. But there's a catch: you want to send these cupcakes as gifts to your friends, and you need to put them in a nice box for that.

Here's where the wrapper comes in:

Wrapper Box: Think of a wrapper class like a fancy cupcake box. Instead of sending just the cupcakes (primitive data), you're putting each cupcake in a special cupcake box (wrapper class). This box can be decorated, labelled, and handled in a more sophisticated way.

In this analogy, the cupcakes represent primitive data types like int or char, and the cupcake boxes represent wrapper classes like Integer or Character.

When you want to give someone a cupcake as a gift, you put it inside a cupcake box and give them the box. Similarly, when you want to use a primitive value in more advanced situations, like collections or methods that require objects, you put it inside a wrapper class and use that object.

What is Wrapper Class?

A wrapper class in Java is a type of reference data type that helps you treat primitive data types as if they were reference data types. Normally, primitive data types are straightforward values like numbers or characters, and they lack the abilities that reference data types have, like having methods or being used in more complex programming tasks.

Wrapper classes, such as Integer or Character, create an object-like "wrapper" around these simple values. This lets you use them in situations where reference data types are expected, like when you want to put them in collections or perform more advanced operations on them. Essentially, wrapper classes bridge the gap between the simplicity of primitive data types and the capabilities of reference data types in the world of Java programming.

What is Primitive and Reference data type?

Primitive Data Types:

When you declare a variable with a primitive data type, the actual value is stored directly in the memory location associated with that variable. This memory location is typically part of the stack memory. For example:

int x = 10; // Here, the value 10 is directly 
            //stored in the memory location of 'x'.

In this case, the memory for the integer x is allocated on the stack and the value 10 is stored directly there.

Reference Data Types:

When you declare a variable with a reference data type (like classes, arrays, and interfaces), the variable stores a reference or memory address pointing to the actual data, which is stored in the heap memory. For example:

String text = "Hello"; // Here, 'text' holds a reference to the 
                         //actual string data stored in the heap.

In this case, the variable the text holds a reference pointing to the actual string data "Hello", which is stored in the heap memory.

Objects are reference data types. Hence I might use these terms interchangeably in the parts ahead

What was the need for a wrapper class in JAVA?

The creation of wrapper classes in Java was driven by the need to treat primitive data types as objects. In an object-oriented programming environment like Java, most operations and features revolve around objects. However, primitive data types (like int, char, etc.) are not objects; they are simple values.

Here are some reasons that led to the creation of wrapper classes:

  1. Object-Oriented Paradigm: Java promotes an object-oriented programming paradigm, where everything is an object. Primitive types didn't fit this paradigm because they lacked the capabilities and behaviours associated with objects.

    a. Lack of Behavior (Methods): Primitive data types, like int, char, and boolean, only hold simple values and don't have associated behaviours or methods.

    b. Limited Functionality

    c. Inability to Model Real-World Entities: Primitive data types don't map directly to real-world entities. You can't create an object that fully represents a concept like "a number" or "a letter".

    d.Lack of Encapsulation: Primitive data types don't naturally support this encapsulation; they're just values without methods associated with them.

  2. Collections and Generics: Java's collections (like lists, sets, and maps) and generics work with objects. To use primitive types in collections or with generics, there needed to be a way to wrap them in objects.

  3. Methods That Require Objects: Many Java libraries and APIs expect objects as parameters. Wrapper classes allow you to use primitive values in these methods by wrapping them in objects.

  4. Uniformity: By using wrapper classes, Java achieves a uniform approach to data types. Whether you're dealing with a primitive type or an object, you can use similar syntax and methods.

  5. Additional Functionality: Wrapper classes provide methods for conversions, parsing, comparisons, and other operations that make working with data more convenient.

  6. Nullability: Primitive types cannot hold null values, which can be limiting in some scenarios. Wrapper classes can hold null values, making them more versatile.

  7. Legacy Code Compatibility: Java's object-oriented design made it easier to integrate newer code with legacy code that might have been designed with primitive types.

  8. Enhanced Type Safety: Wrapper classes, when used properly, can help enhance type safety in your code by reducing the chances of mixing incompatible data types.

Overall, the creation of wrapper classes aimed to bridge the gap between primitive data types and object-oriented programming. It made Java more consistent, provided greater flexibility, and allowed developers to leverage Java's features more effectively, especially in the context of collections, generics, and other object-centric constructs.

Application of a Wrapper Class

Imagine you want to keep track of scores for a game using an ArrayList, but scores are primitive data types. You need a way to store these scores as objects to use them in collections.

Here's how you can do it using the Integer wrapper class:

import java.util.ArrayList;

public class WrapperClassExample {
    public static void main(String[] args) {
        // Creating an ArrayList to store scores
        ArrayList<Integer> scoresList = new ArrayList<>();

        // Adding scores using Integer wrapper objects
        scoresList.add(new Integer(100)); // Wrapping int in an Integer object
        scoresList.add(new Integer(85));
        scoresList.add(new Integer(150));

        // Accessing and using scores from the list
        for (Integer score : scoresList) {
            System.out.println("Score: " + score);
        }
    }
}

In this example:

  1. We create an ArrayList named scoresList that stores Integer objects.

  2. We use the new Integer(value) constructor to wrap primitive scores in Integer objects before adding them to the list.

  3. When we loop through the list using a for-each loop, we access and print each score using the Integer objects.

Here, the Integer wrapper class enables us to use primitive int scores as if they were objects. This is crucial when working with collections that require objects, demonstrating how wrapper classes facilitate advanced concepts like storing data in collections in a more object-oriented way.