"개발자는 숫자를 설명하는 클래스를 만들 수 있기 때문에 실제 개발자처럼 창의적이기로 결정했습니다."

"첫째, 그들은 Byte, Short, Integer, Long, Float 및 Double이 파생되는 추상 Number 클래스를 생각해 냈습니다. 여기에는 숫자를 다른 숫자 유형으로 변환하는 데 도움이 되는 메서드가 있습니다."

Number 클래스의 메서드
1
int intValue()
2
long longValue()
float floatValue()
4
double doubleValue()
5
byte byteValue()
6
short shortValue()

"맞아요. 결국 이렇게 쓰면 안 돼요."

Long x = 100000;
Integer y = (Integer) x;

"예, 이러한 유형은 프리미티브가 아닙니다. 이것이 우리가 Number 클래스의 메서드를 사용하는 이유입니다."

Long x = 100000;
Integer y = x.intValue();

"그러나 여전히 고려해야 할 몇 가지 사항이 있습니다. Integer는 int가 아니기 때문에 Integer 개체는 고전적인 «==» 연산자와 비교할 수 없습니다."

기본 유형 비교
int x = 500;
int y = 500;
x == y; //true
기본이 아닌 유형 비교
Integer x = 500;
Integer y = 500;
x == y; //false
x.equals(y); //true

"맞아요. 어쩐지 갑자기 그런 생각이 안 났어요."

"하지만 더 있습니다."

"당신은 내 회로를 단락시키고 있습니다! 또 무엇이 있습니까?"

"Integer 변수에 int 값을 할당하면 Integer.valueOf 메서드가 호출됩니다."

암호 실제로 일어나는 일
Integer x = 5;
Integer x = Integer.valueOf(5);

"예, 위의 예에서 이미 이해했습니다."

"그러나 valueOf 함수가 항상 새로운 Integer 객체를 생성하는 것은 아닙니다."

"어, «언제나 그렇지는 않다»는게 무슨 뜻이야?"

"-128에서 127까지의 값을 캐시합니다."

암호 실제로 일어나는 일 설명
Integer x = 300;
Integer y = 300;
Integer z = 300;
Integer x = Integer.valueOf(300);
Integer y = Integer.valueOf(300);
Integer z = Integer.valueOf(300);
변수 x, y 및 z는 다른 개체에 대한 참조를 포함합니다.
Integer x = 100;
Integer y = 100;
Integer z = 100;
Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
Integer z = Integer.valueOf(100);
변수 x, y 및 z는 동일한 개체에 대한 참조를 포함합니다.
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = 10;
Integer t = 10;
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = Integer.valueOf(10);
Integer t = Integer.valueOf(10);
변수 z와 t는 동일한 개체에 대한 참조를 포함합니다.

"즉, 상황은 이렇습니다."

1)  «new Integer()»를 작성하면 새 객체를 얻을 수 있습니다.

2)  명시적으로 또는 오토박싱을 통해 Integer.valueOf()를 호출하면 number 인수가 -128에서 127 사이의 범위에 있으면 메서드가 새 개체 또는 캐시된 개체를 반환할 수 있습니다.

"캐시에서 객체를 반환하는 메소드가 왜 그렇게 끔찍한가요?"

"신경 쓰지 마세요. 때때로 예상치 못한 경우 개체가 같을 수 있다는 사실을 알아야 합니다. 평등이 있는 모든 것은 복잡합니다. 프리미티브를 프리미티브가 아닌 것과 비교하면 프리미티브로 비교됩니다."

비교 문제
int x = 300;
Integer y = 300;
Integer z = 300;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references)
훨씬 더 흥미로운 예입니다. 캐시는 여기에 그림을 입력합니다
int x = 100;
Integer y = 100;
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //true (comparison based on references; they point to the same object)
그러나 캐시는 여기에 관여하지 않습니다
int x = 100;
Integer y = new Integer(100);
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references; they point to different objects)

"좋아요... 그런데 이걸 어떻게 다 외우죠?"

"이것을 외울 필요는 없습니다. 이 모든 것이 어떻게 구성되어 있는지, 그리고 프리미티브와 비프리미티브가 작동할 때 실제로 어떤 일이 일어나는지 이해하면 됩니다."

"또한 Integer 클래스의 메서드를 살펴보는 것이 좋습니다. 훌륭하고 유용한 메서드가 꽤 많이 있습니다. 심지어 그 중 하나를 꽤 자주 사용했습니다."

"그래, 기억나. Integer.parseInt();"