Search code examples
javaintegerintwrapperprimitive

What is the real difference between primitives and wrapper classes in Java


I understand stuff like:

  1. Wrapper class creates an object and primitive does not create object
  2. Wrapper classes are used with Collections to represent type
  3. Wrappers have methods and can hold memory address/null and primitives hold default values
  4. Primitives are fast compare to wrapper classes as there is no overhead of methods or object
  5. How auto boxing and unboxing works
  6. Wrapper class wraps primitive type

However, not able to understand the real difference between primitives and wrapper classes. Why there was a need to create two different ways to hold the data? Why we did not reuse what was already available? For example, if wrapper classes were introduced before primitives then why we did not use wrapper classes instead of developing altogether a different way for similar purpose and vice versa.


Solution

  • The real difference is that primitive types are not reference types.

    In Java type system, reference types have a common root, while primitive types do not: All reference types are subtypes of Object. In comparison, primitive types do not have a common root; each primitive type is its own special unicorn.

    This means that a variable declared with Object type can hold a value of any reference type, but it cannot hold a value of any primitive type.

    This is a problem if you want to create data structures that are generally useful. Consider how you would implement a "dynamic array" data structure like ArrayList or Vector. You could use an array Object[] to store the elements, and that would work for all reference types. But since primitive types don't have a common root you would have to create a separate implementation for each primitive type.

    To solve this problem, wrapper classes were created. Now, instead of needing 8 separate implementations of dynamic array (1 for reference types and 7 for primitive types), you could wrap each primitive value in an object, and just use the implementation for reference types.

    Primitive types and wrapper classes were created at the same time, when the first design and implementation of Java 1.0 were made. The designers did not "reuse what was already available" because nothing was available: they built everything from scratch.

    Could the designers have solved the problem some other way, maybe by creating a type system that had a common root for both primitive and reference types? Yes, but they didn't, and they probably had good reasons: implementation complexity, ease of understanding, time to market, ...