Why in java is there a wrapper for every primitive type
Asked Answered
S

12

19

The Number subclasses wrap primitive numeric types (Byte, Integer, Double, Float, Long, and Short).

What purpose do they serve?

Sulphanilamide answered 18/1, 2012 at 19:24 Comment(3)
basically every single answer mentions that being able to add the wrapper classes to the default Collections is part of the reason. However it should be noted that when you have millions and millions of such primitives wrapped and unwrapped in, say, HashMap<Integer,Long> etc. you can get gigantic memory and speed boost by using 3rd party primitive-backed collections like Trove and its TIntLongHashMap etc. So it's "convenient" to be able to put an (int,long) entry into an HashMap but it's hardly an efficient way to operate. The amount of bloat is actually amazing.Jaquelinejaquelyn
I would include Boolean which is not a Number and Void which is notionally a wrapper for voidMercurochrome
There is also Character, which is likewise not a Number (in that it doesn't extend Number).Nayarit
T
18

Those wrapper classes were created so that there was some way to use those primitive types with various container classes like ArrayList. Since primitive types can't directly be coerced into Object references, they are stored in wrapper classes to allow them to be used where Object references are required.

Teressaterete answered 18/1, 2012 at 19:26 Comment(1)
The wrapper classes also encapsulate helpful behavior corresponding to the respective primitive type. Say you want to convert a string representation of a double into an actual double. Double.parseDouble(String) does just that. Also, let me just cook up an example... consider an Employee object with an attribute called salary. Typically, this would be of type double. Say the employee is just being recruited and so added to the system, but the salary has not been input. A double would assume the default value of 0. A value of null might make a lot more sense than 0 :)Holdall
R
12

Because the wrappers are Objects.

  • Collections needs Objects
  • Objects can be instantiated to null
  • We can get NullPointerException instead of strange behavior if you for example instantiate to -1 in a primitive
  • The "wrapper" has convenient methods
Repast answered 18/1, 2012 at 19:26 Comment(0)
D
5

Many early object oriented languages (Smalltalk etc.) have a common "top type" for all values which makes it easier to define generic operations that are agnostic to the type of values they shuttle around.

The top type in type theory, commonly abbreviated as top or by the down tack symbol (⊤), is the universal type—that type which contains every possible object in the type system of interest.

Java does not have such a top type, but Object is the closest it has. Having a mapping from primitive values to instances of Object allows it to effectively function as a top type.

Core language facilities java.lang.reflect use Object as a stand-in for the top type -- when you reflectively invoke a method you pass in Objects and get back an Object.

Duthie answered 18/1, 2012 at 19:28 Comment(0)
A
2

As per this link java tutorial reasons are:

There are three reasons that you might use a Number object rather than a primitive:

  • As an argument of a method that expects an object (often used when manipulating collections of numbers).
  • To use constants defined by the class, such as MIN_VALUE and MAX_VALUE, that provide the upper and lower bounds of the data type.
  • To use class methods for converting values to and from other primitive types, for converting to and from strings, and for converting between number systems (decimal, octal, hexadecimal, binary).
Adjure answered 18/1, 2012 at 19:30 Comment(0)
P
2

The Java designers have - for good reasons or bad - chose not to base all types on Object. Primitive types like int, long, char, etc. are not based on Object and because of that they have rather different semantics, like that they are passed by value rather than by reference.

Integer/Long are basically just wrapper classes to make the primitive types behave like any other type to be able to use them in contexts where classes or objects are a better fit.

For example, due to the difference in semantics, collections would have to have two versions, one for Object and one for primitive types. It's just easier to make a single version of the collection and wrap the primitive types instead.

Punke answered 18/1, 2012 at 19:34 Comment(12)
I think the main reason they chose to have a reference type/primitive type distinction was so they could avoid heap allocation of primitives that are used in local variables. They could have adopted a richer selfless/selfish value distinction but that would have complicated the language.Duthie
@MikeSamuel: I hadn't heard things described in such terms, but I think having one universal type of object reference makes for a semantically weak language, since a field of type list<string> might depending upon circumstance encapsulate the identity of the referred-to object, its present mutable state, both, or neither (just encapsulating state that will never change). Were it not for the linguistic failure to identify which aspects of an object are encapsulated in a field, things like object cloning and object equality could be handled declaratively rather than imperatively.Hydrosome
@supercat, I'm not sure I follow. Scala manages to build rich equivalence for algebraic data types on top of Java's object model just fine, so it seems to me that the lack of declarative comparison/copy operators in Java is a matter of priorities, not due to a flaw in the type system.Duthie
@MikeSamuel: I know nothing about Scala, but the semantic weaknesses I'm talking about would be a function of the language more than the JVM, since they'd mostly relate to compile-time validation and human understanding, rather than run-time behavior. Such declarations, for example, could resolve the ambiguity of whether a GetCustomer(int id) method should return a mutable object which is bound to the data store (which would "own" the state thereof), or return an object which is mutable but is not bound (whose state would be owned by the caller).Hydrosome
@supercat, You can add all kinds of flourishes to type systems. Gilad Bracha's, who worked on Java annotations, argues for pluggable type systems. The idea is that different kinds of programs benefit from different static checks (like DB consistency), and a generally useful programming language should provide support for those checks. Java was not designed for pluggability but it is headed in that direction via its annotation framework. See Safety Checking ... for an example.Duthie
@MikeSamuel: My beef with Java is that many things end up being encapsulated in the type of an object they they should instead be characteristics of variables, fields, parameters, etc. For example, it would be helpful to be able to specify that a parameter, variable, or field, should have certain restrictions on its use, and that it could not be downcast nor copied to a parameter, variable, or field which lacked such a restriction. A type could, for example, specify that certain methods should be unavailable on "restricted" variables etc. One could simulate...Hydrosome
...such a thing by defining a wrapper class, and hand-coding wrappers for all the methods which were supposed to still be available so they'd invoke the corresponding methods on the wrapped object, but that is a real pain. Further, such wrappers don't interact very well with inheritance. If an object has only exposed references to an object to methods which were explicitly forbidden from persisting such references, and all such methods have returned, the object may be freely mutated without "surprising" anyone who has received a temporary reference to it. An object could if desired...Hydrosome
...provide a method which would return a persistent reference to its nested object, but which would set a flag indicating that it would need to perform a copy-on-write the next time it was modified. For such an approach to work, though, it's necessary to have a means of distinguishing ephemeral and persistable references.Hydrosome
@supercat, You are correct that static type systems do a bad job with wrapping. lambda-the-ultimate.org/node/1625#comment-19906 talks about similar problems with OCaml and membranes. Re "characteristics", is this a criticism of the core libraries? If not, then it seems that this criticism would equally well apply to all languages with structured types that allow programmers to gloss over "is-a" vs "has-a" distinctions. If you're interested in ephemeral references, I strongly suggest you check out Mark Miller's thesis that is linked from that comment and how he deals with reference.Duthie
@MikeSamuel: I dislike "is a" and "has a" terminology; I prefer to think in terms of substitutability. As for ephemeral references, I don't have time now to read a 229-page paper, but a lot could be done if a framework recognized three types of references: persistent, ephemeral, and returnable. Ephemeral references could not be stored anyplace which would outlive the present scope, nor returned. Persistent references could be stored anywhere. Returnable references would be like ephemeral references except that they could be returned from a function; the return value of a function...Hydrosome
...which had any returnable-reference parameters would be bound by the tightest restriction of any of its "returnable" arguments. In a framework which includes composite value types (structures), I think those are all that would be needed to achieve 99% of the benefit such references could provide. In a framework without structures, it would be necessary to add some special declarative sauce to certain class types; that might be a good thing anyway, though, since it would increase the achievable complexity of statically-verifiably-immutable data structures.Hydrosome
For example, a constructor could specify that a parameter will not be stored anywhere persistent except in a field of the object under construction, and that it would not expose the object under construction to any outside code that might persist it, except such a restricted parameter to a constructor whose return would be treated similarly. I'd be happy to chat more about such notions if you like; they're getting off-topic here.Hydrosome
A
1

The wrapper classes in the Java API basically serve two primary purposes:

  • To let the primitives be included in activities reserved for objects, like as being added to Collections, or returned from a method with an object return value.
  • To provide an assortment of utility functions for primitives. Most of these functions are related to various conversions: converting primitives to and from String objects, and converting primitives and String objects to and from different bases (or radix), such as binary, octal, and hexadecimal.
Alevin answered 18/1, 2012 at 19:29 Comment(1)
Good answer. I'd also add that the wrapper classes allow you to use null, instead of initializing to 0 or -1 (which in some situations might be a valid values).Fimble
P
0

To treat them as objects and put them into List, Maps etc

Pointing answered 18/1, 2012 at 19:26 Comment(1)
To elaborate on this answer, Java Generics only work on types that derive from type Object. Therefore in order to use classes such as ArrayList<T>, primitives need to have object type wrappers.Biomass
T
0

So, that we are able to add primitive data types into collections. To add elements into collection they have to be of type objects. So, Wrapper classes were introduced which let us create objects of primitive data types.

For example:

Arraylist :   add(Object o) 

TreeSet:      add(Object o) 
Transmundane answered 18/1, 2012 at 19:27 Comment(0)
B
0

Personally, I use them as parameters for methods so i don't have to worry about the type of number being passed in. Then I can use methods like doubleValue() to get the value out and can carry on without worrying about what was passed in.

This is the basic reason to ever have an Abstract Base Class.

Bencion answered 18/1, 2012 at 19:31 Comment(0)
B
0

There is a specific type of "pointer" that can point to any type (like void in C/C++).

I am referring to java.lang.Object.

E.g. you can do this:

List<String> aList = new ArrayList<String>();  
Object o = aList;

BUT this is not available for primitives i.e. there is no void reference type for primitives. I.e. there is no way for a primitive type to refer to any kind of primitive type.

So if you want to have an algorithm that operates on arbitrary variables you can use variables of type java.lang.Object.
If the arbitrary values are primitives, use the appropriate Object Wrapper to wrap them and use java.lang.Object references to manipulate them.

You can see this in Collections as well

Betterment answered 18/1, 2012 at 19:38 Comment(0)
A
0

Wrapper classes are the object representatives of primitive data types so whenever there is a situation to use them as objects we have to use them. Wrapper usage when we need objects and primitive when efficiency is required.

Amadeus answered 2/7, 2012 at 10:30 Comment(0)
H
0

1st-in order to make java fully object oriented.

2nd-we can't pass a primitive type by a reference to a method and many of the standard data structure implemented by java operates on object:eg(ArrayList,HashSet,HashMap,etc),so they need these object referenc

Hyperion answered 30/9, 2013 at 5:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.