# Caching in Wrapper Classes Here’s a fact that you may not know. When you auto-box integral primitives (`byte``short``int` and `long`) to their respective wrapper classes (`Byte``Short``Integer` and `Long`), the wrapper classes cache all values from `-128` to `+127`. These values are later used by the `valueOf()` methods to give better performance than using a constructor.

## Auto-boxing

Let’s use an example of auto-boxing an `int` into an `Integer`.

`Integer a = 33;`

Behind the scenes when the compiler generates code to auto-box the `int`, it uses the static `Integer.valueOf()` method. The `valueOf()` method first checks the cache. If the value to be auto-boxed falls in the range `-128` to `+127`, then it returns the previously-created cached `Integer`. Otherwise it creates a new `Integer` object. This yields better performance for commonly used values.

## Example

Let’s look at a code snippet:

```Integer a = 33;  // same as Integer a = Integer.valueOf(33);
Integer b = 33;
Integer c = new Integer (33);
System.out.printf("a == b : %b%n", a==b);
System.out.printf("a == c : %b%n", a==c);
System.out.printf("a.equals(b) : %b%n", a.equals(b));
System.out.printf("a.equals(c) : %b%n", a.equals(c));
```

Comparing `a` and `b` with the `==` operator returns `true`, while `a == c` returns `false`.

Both `a` and `b` refer to the same object in the cache, while `c` refers to a new `Integer` object on the heap. Using the `equals()` method will always return `true`.

Now let’s change the values of `a``b` and `c` to the following:

```Integer a = 133;
Integer b = 133;
Integer c = new Integer (133);
System.out.printf("a == b : %b%n", a==b);
System.out.printf("a == c : %b%n", a==c);
System.out.printf("a.equals(b) : %b%n", a.equals(b));
System.out.printf("a.equals(c) : %b%n", a.equals(c));
```

Now `a == b` returns `false` because they refer to different objects. This is because their values are outside the range of the cache limits. New `Integer` objects have been created for each value when auto-boxed.

## Changing the Cache Limit

We can change the upper cache limit, but not the lower limit. When starting the JVM, we can use either of two options (the `xxx` is the value you want for the upper limit):

`java -Djava.lang.Integer.IntegerCache.high=xxx MyClass`

or

`java -XX:AutoBoxCacheMax=xxx MyClass`

The `-D` option will always work, but the `-XX:` option is non-standard, and may not be supported by the compiler you are using.

## Why do you have to know this?

There are practical implications of caching other than just performance. Not knowing about the cache can lead to unexpected behaviour when comparing wrapped integral numbers which may take you a lot of time and effort to track down. And as an added knowledge bonus, it’s also a common question in certification exams.