## 1. `Integer` class

`Integer` is also good in that it is a class, which means that it can have fields and methods. And, of course, it has them. A lot of them — dozens of them. Here we'll consider the most basic ones.

The `Integer` class has two fields that contain the maximum and minimum possible values of the `int` type:

Field Description
``Integer.MAX_VALUE``
Maximum possible value of the `int` type
``Integer.MIN_VALUE``
Minimum possible value of the `int` type

Sometimes you want to assign the smallest or largest possible `int` value to a variable. To avoid cluttering up your code with incomprehensible constants, you can write this very clearly as follows:

Code Description
``int min = Integer.MIN_VALUE;``
``min == 0x80000000``

The `Integer` class also has some interesting methods. Here they are:

Methods Description
``String Integer.toHexString(int)``
Returns a string that is the hexadecimal representation of the number
``String Integer.toBinaryString(int)``
Returns a string that is the binary representation of the number
``String Integer.toOctalString(int)``
Returns a string that is the octal representation of the number
``Integer Integer.valueOf(int i)``
Wraps the passed `int` in an `Integer` object
``Integer Integer.parseInt(String)``
Returns the number obtained from the passed string

You previously encountered the static `Integer.parseInt()` method. Let's recall how it works:

``int name = Integer.parseInt(string);``

If a string containing a number (only digits) is passed to the `parseInt()` method, it will parse the string and return the number it contains.

The rest of the methods are also useful. For example, some of them can convert a passed number to a string containing the binary, octal or hexadecimal representation of the number.

## 2. `Double` class

In general, the `Double` class is similar to the `Integer` class, only it wraps a `double` rather than an `int`. It also has fields and methods that will be of interest to us. Consider a few of them:

The `Double` class has six interesting fields:

Field Description
``double Double.NEGATIVE_INFINITY``
Negative infinity
``double Double.POSITIVE_INFINITY``
Positive infinity
``int Double.MIN_EXPONENT``
Minimum possible exponent (2x)
``int Double.MAX_EXPONENT``
Maximum possible exponent (2x)
``double Double.MIN_VALUE``
Minimum possible value of the `double` type
``double Double.MAX_VALUE``
Maximum possible value of the `double` type

Infinity

If you divide `-1.0` by `0.0`, you get negative infinity. If you divide `1.0` by `0.0`, you get positive infinity. Not only can you divide a `double` by zero, but you can also use it store the result of these operations.

Exponent of a `double`

Understanding the exponent is easy. Internally, a double consists of a mantissa and an exponent. But here the value of the exponent is not `10x`, but `2x`. Thus, if the exponent increases by `1`, the total value of the number will double.

`MIN_EXPONENT == -1024`, which means `2-1024`, which is approximately equal to `10-308`

And of course, the `Double` class has interesting methods:

Methods Description
``String Double.toHexString(double)``
Returns a string that is the hexadecimal representation of the number
``boolean Double.isInfinite(double)``
Checks whether the passed number is infinity.
``boolean Double.isNaN(double)``
Checks whether the passed number is `NaN`
``Double Double.valueOf(double)``
Wraps the passed `double` in a `Double` object
``Double Double.parseDouble(String)``
Returns the number obtained from the passed string

Interestingly, there is an `isInfinite()` method that returns `true` if the passed number is positive or negative infinity.

The `isNaN()` method is similar — it checks whether the passed number is `NaN` (Not-a-Number, a special constant that indicates an undefined value).

## 3. `Character` class

The `Character` class is interesting primarily for its large number of static utility methods that let you check whether characters belong to various categories.

Examples

Methods Description
``Character.isAlphabetic(int)``
Checks whether a character is an alphabetic character
``Character.isLetter(char)``
Checks whether the character is a letter
``Character.isDigit(char)``
Checks whether the character is a digit
``Character.isSpaceChar(char)``
Checks whether the character is a space, a line break, or a page break (codes: 12, 13, 14)
``Character.isWhitespace(char)``
Checks whether the character is whitespace: a space, tab, etc.
``Character.isLowerCase(char)``
Checks whether the character is lowercase
``Character.isUpperCase(char)``
Checks whether the character is uppercase
``Character.toLowerCase(char)``
Converts the character to lowercase
``Character.toUpperCase(char)``
Converts the character to uppercase

A feature of these methods is that they work with all known alphabets: Arabic numerals are classified as digits, etc.

## 4. `Boolean` class

The `Boolean` type is virtually the same as the `boolean` type. The differences are minimal.

Below we show a simplified version of the `Boolean` class:

Code Description
``````class Boolean
{
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

private final boolean value;

public Boolean(boolean value)
{
this.value = value;
}

public boolean booleanValue()
{
return value;
}

public static Boolean valueOf(boolean value)
{
return (value ? TRUE : FALSE);
}
}``````

Constants: `TRUE` and `FALSE`

Variable

`Boolean` class constructor

The method returns the value of the internal variable

This static method converts `true` to `TRUE` and `false` to `FALSE`.

The `Boolean` type has two constants (two fields):

Constants of the class Counterpart for the boolean type Description
``Boolean.TRUE``
``true``
true
``Boolean.FALSE``
``false``
false

You can work with them in the same way that you work with the `boolean` type:

Code Note
``````if (Boolean.TRUE)
{
}``````
The `Boolean` class is the only class that can be written inside a condition
``````Boolean a = Boolean.TRUE;
boolean b = Boolean.TRUE;
boolean c = true;``````
All three variables are equal to `true`/`TRUE`
``````Boolean a = Boolean.TRUE;
Boolean b = Boolean.TRUE;
if (a == b)``````
Constants can be compared using both `equals` and `==`

This will also work.

Autoboxing works great here. That means you can use this type in the same way as the `boolean` type — there are no pitfalls to watch out for.

How it is written How it works
``````Boolean a = true;
Boolean b = true;
Boolean c = false;
boolean d = a;``````
``````Boolean a = Boolean.valueOf(true);
Boolean b = Boolean.valueOf(true);
Boolean c = Boolean.valueOf(false);
boolean d = a.booleanValue();``````

And here a comparison of the `boolean` and `Boolean` types:

``````boolean a = true;
Boolean b = true; // b will be equal to Boolean.TRUE
Boolean c = true; // c will be equal to Boolean.TRUE

a == b; // true (compared by value)
a == c; // true (compared by value)
b == c; // true (compared by reference, but they point to the same object)``````

If you really need an independent `Boolean` object, then you need to create it explicitly:

``````boolean a = true;
Boolean b = new Boolean(true); // New Boolean object
Boolean c = true; // c will be equal to Boolean.TRUE

a == b; // true (compared by value)
a == c; // true (compared by value)
b == c; // false (compared by reference, and they point to different objects)``````

One more example, where we'll use a `Boolean` inside of an `if`:

Code Note
``````Boolean less = (2 < 3);
if (less)
{
...
}``````
This will compile and work

This will compile, but it won't work!

Code Note
``````Boolean less = null;
if (less)
{
...
}``````

Error. This line will throw an exception

## 5. Caching values during autoboxing

There are some pitfalls related to integer wrapper types.

As you already know, if we compare an `int` and an `Integer`, the `Integer` is converted to an `int`:

How it is written How it works
``````int a = 5;
Integer b = 5;
if (a == b)
{
...
}``````
``````int a = 5;
Integer b = Integer.valueOf(5);
if (a == b.intValue())
{
...
}``````

If you compare two `Integer` objects with each other, they are not converted to `int`s:

Code Console output
``````Integer a = 500;
Integer b = 500;
int c = 500;

System.out.println(a == b); // Compared by reference
System.out.println(a == c);
System.out.println(b == c);``````
``````

false
true
true``````

`a == c` and `b == c`, but `a != b`, because when we compare `a` and `b` we are comparing references. Which is essentially what we would expect.

Surprise

But if we replace `500` with `100`, then we get a completely different result:

Code Console output
``````Integer a = 100;
Integer b = 100;
int c = 100;

System.out.println(a == b); // Compared by reference
System.out.println(a == c);
System.out.println(b == c);``````
``````

true
true
true``````

The issue here is that a new `Integer` object is not always actually created during autoboxing. Objects are cached for values `-128` through `127` inclusive.

The `Integer` class has a hidden array that stores objects: `Integer(-128)`, `Integer(-127)`, ... `Integer(126)`, `Integer(127)`

If you write `Integer x = 128`, then the autoboxing process creates a new object, but if you write `Integer x = 127`, then the autoboxing process retrieves the existing object from the cache (from the array).

If you don't want the `Integer` object to come from the cache, you will have to create it explicitly by writing: `Integer x = new Integer(127);`

All wrapper types have such a cache: `Integer`, `Long`, `Byte`, `Short`, `Boolean`. For the `Boolean` type, its `TRUE` and `FALSE` values are both constants, so they are also essentially cached.