Hi there!
For the next section of videos, we're going to focus on the String and Number classes.
Let's start with the number classes, and then we'll talk about how Java uses autoboxing
and unboxing to convert these classes to and from Java primitives.
In earlier videos we looked at the primitive data types for numbers.
The primitive Java types were the bytes, shorts, ints, longs, floats, and doubles.
The java.lang package includes the wrapper classes for each of these primitive data types.
For example, the byte primitive has a matching Java class called Byte.
The difference when declaring a Java variable using a class is the class version is uppercase.
That's because all classes in Java are declared starting with a capital letter by convention.
A wrapper class is a class that "wraps" the functionality of another class or component.
We'd do this to add functionality to an existing class without using inheritance, or converting
a primitive data type into a class.
In this case, the wrapper classes are "wrapping" a Java primitive type.
All of the number types are subclasses of the Number class.
The Number class contains methods to return the value as different primitive types.
The other difference is the matching class for ints are Integers.
I think the reason is int matches closely with C primitives, the language Java mimics.
There's no defined class in C for integers, so in Java they were free to use the full
word for the class.
The number classes also include BigInteger, BigDecimal, AtomicInteger, and AtomicLong.
BigInteger and BigDecimal are used for high precision applications where you need to accurately
represent the number.
Other than a cool sounding name, AtomicInteger and AtomicLong are used for multi-threaded
applications.
We'll cover these classes in later lessons.
You're probably wondering, why?
Why do we have classes for numbers, when we already have the number primitives.
There's several reasons.
First there are other classes with methods which expect objects as the parameter.
The main ones are Java collection classes.
We'll have many lessons discussing the Java collection classes, but these classes represent
things like linked lists and they only hold classes.
The other reason is these classes have defined constants and methods associated with the
number type.
For example, the number classes have constants like the maximum and minimum values.
So we never need to memorize this long number!
It's much easier to read MAX_INT than a long string of digits, and we'll never type it
wrong.
The number classes also have many methods for manipulating the data type, like converting
integers to a hexadecimal or binary representation.
We're going to cover many of these methods in the next few lessons.
For right now, let's look at how Java converts between the class and primitive numbers
Java converts between numbers and primitives automatically using something called autoboxing
and unboxing.
Autoboxing is when Java automatically converts a number primitive to an instance of the corresponding
number class.
The simplest example of this is when you declare a number class instance.
We know we can create a class instance using the new keyword.
We've done this many times, and for the number classes we can pass the number we want as
an argument to the constructor.
So here we are creating an Integer instance with the value of 42.
This is a special rule in the Java language, but you can also define the number like you
would create a primitive.
That looks like this.
What happens is the compiler converts the number 42 to an integer class by replacing
the declaration to look like this.
The valueOf method takes a primitive, and returns an instance of the class.
This happens automatically.
We never see it happen in our code.
This is autoboxing.
Autoboxing also happens when you pass a primitive to a method expecting a object.
For example, if we had a method like this, we can pass an primitive.
Java will convert it to a class instance for us.
Again, this is automatic.
Unboxing happens in the other direction.
This is when we have the number class, but Java is expecting the primitive.
In this case, Java "unboxes" the primitive from the wrapper class.
For example, let's use the Integer class in an if-then test.
We create the integer, perform an operation on it, and then the test.
Remember i in this example is an instance, not a primitive.
Still Java knows to unbox the instance into a primitive.
Behind the scenes, the compiler is replacing our code with the intValue method.
Java is doing this automatically for us.
This is called unboxing.
The next question we're likely asking is, why use primitives at all.
Primitives have their value and nothing more.
Boxed values have identities associated with the object.
This value is immutable, so once you create a class with the value it cannot be changed.
This means that two boxed values can have different identities.
Usually.
There's a weird quirk to this, and if you want to know more about it, check out the
weird Java number tricks video.
Boxed values also have the possibility to be null, meaning the instance can have a primitive
value or no value.
We could get into a case where we think we're comparing numbers, but the instance gets us
into trouble.
Imagine we create an Integer instance, but we never create a value.
The instance is null.
Now compare the number in an if statement.
This gives us a NullPointerException.
The reason is we're unboxing the number by calling the intValue method, but the method
is not a static method.
It's an instance method, but our instance is null.
So boom.
The key to remember is when we autobox or unbox, behind the scenes a method is getting
called.
This can lead to performance penalties if we're doing this for millions of numbers.
We should always prefer primitives if we can get away with it.
That's it for Java autoboxing and unboxing.
If you have any questions, add them to the comments below.
Next we'll look at the methods and constants inside the Number classes.
Liking the video helps me know what I'm doing right, so if you liked the video... you know
what to do.
And with that, I’ll see you in the next tutorial!