기본타입 | 래퍼 클래스 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Wrapper class란 자바의 기본 데이터 타입(primitive)을 객체 형태의 참조타입으로 만든 것이다. primitive를 객체로 감싼다는 의미로 "wrap"을 사용한다. 모든 기본 데이터 타입은 그와 관련된 클래스를 가지는 것이다. int와 char형태만 달라지는 것에 유의하며, 참고로 이 8가지의 기본타입 때문에 자바를 100% 객체지향언어라고 할 수 없다.
박싱(Boxing)과 언박싱(UnBxoing)
박싱(Boxing) : 기본타입 -> 래퍼클래스로 변환
언박싱(UnBoxing) : 래퍼클래스 -> 기본타입 변환
class Test{
Integer num1 = new Integer(17); // 박싱
int num2 = num1.intValue(); // 언박싱
}
자동 박싱(Auto-Boxing)과 자동 언박싱(Auto-UnBoxing)
class Test{
Integer num = 17; //오토박싱
int n = num; //오토언박싱
}
먼저 살펴 볼 코드는 간단한 예제이다. 코드에서는 Integer num이 int처럼 단순한 변수로 선언된 것으로 보이지만 자동박싱 덕분에 가능하며 num객체가 생성된다.
class Test{
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++)
list.add(i); //개발자 코드
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++)
list.add(Integer.valueOf(i)); //내부 코드
}
ArrayList의 제너릭은 Integer인데, list.add(i)에서 왜 int형을 넣을 수 있을까?
자동방식(Auto-Boxing)덕분이다. 기본타입인 int형이 컴파일러에 의해 자동으로 Integer형으로 변한다.
첫번째 list.add(i)는 개발자가 정의한 코드라면, list.add(Integer.valueOf(i))가 컴파일러가 내부적으로 작동하는 코드이다.
JDK 1.5부터 자바 컴파일러가 자동으로 박싱과 언박싱을 처리해준다.
문자열을 기본타입으로 변경하기
public class Test {
public static void main(String[] args) {
String str = "10";
String str2 = "10.5";
String str3 = "true";
byte b = Byte.parseByte(str);
int i = Integer.parseInt(str);
short s = Short.parseShort(str);
long l = Long.parseLong(str);
float f = Float.parseFloat(str2);
double d = Double.parseDouble(str2);
boolean bool = Boolean.parseBoolean(str3);
}
}
래퍼 클래스에서 제공하는 parse를 이용한 메소드를 통해 객체 값들을 기본데이터 타입으로 만드는 경우도 많이 쓰인다.
Integer와 int 변환 및 비교
class Test{
Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
int e = 128;
int f = Integer.valueOf("127");
System.out.println(a==b);//true
System.out.println(a==b);//false
System.out.println(c==e);//true
System.out.println(a==f);//true
}
Integer cache pool은 -128~127의 값을 가지고 있으며 위에서 설명했듯이 int형이 Integer형으로 자동박싱(Auto-Boxing)되는 상황에서 Integer.valueOf() 메소드가 작동된다. 특히 그 int값이 -128~127 사이에 값을 가지고 있는지 확인한다. 구체적인 메소드에 대한설명은 다음과 같다.
Integer.valueOf()는 int i의 값이 -128~127 사이에 있는지 확인하고 그 사이에 있는 값이 맞다면 바로 참조한다. 그렇지 않다면 새로운 객체를 생성하여 값을 만든다.
따라서 a와 b의 비교에서 true가 나온다. c와 d는 값이 128이므로 Integer cache pool에 포함되지 않아 따로 객체를 만들게된다. 따라서 c와 d의 '=='비교는 false를 반환한다. pool값을 바로 참조하지 못하고 각각 따로 주소값을 가지게 되기 때문이다. 하지만 c와 e의 값을 비교 할 경우, Integer와 int의 비교인대, 이 때는 값만을 비교하기 때문에 true를 반환한다. a와 f의 경우 f가 String형을 Integer로 변환하고 있는대, 이 또한 -128~127에 속해 있는지 먼저 확인한다. 따라서 해당 범위 내에 있으면 true를 반환하고 그렇지 않다면 false를 반환한다.
다음 그림을 참고하여 Integer 값에 대한 주소 비교를 쉽게 확인 할 수 있다.
Integer.parseInt() vs Integer.valueOf()
2가지 메소드는 모두 Integer 클래스의 메소드로 기능은 같지만 미묘하게 다른 차이점이 있다. 반환형에 주의해서 살펴본다.
String 문자열을 매개변수로 return을 보면 in decimal이라 하여 int형이다. 즉, String -> int로 한번에 변환시킨다.
String 문자열을 매개변수로 return을 보면 Integer이다. new Integer(Integer.parseInt(s))라고 나와있다. 즉 이 메서드는 String형을 int형으로 변환하고 Integer형으로 박싱(Boxing)하는 것이다. 하지만 보통 우리는 Integer.valueOf()를 int형 변수로도 사용을 많이 하는대 자동언박싱(Auto-UnBoxing) 덕분이다. 하지만 String->Integer, Integer-> int의 2번의 변환 과정이 일어난다.
만약 Integer형으로 사용할 것이라면 상관없지만 int형으로 사용할 것이라면 Integer.parseInt()를 쓰는 것이 낫다.
출처
https://coding-factory.tistory.com/547https://dharashahkenya.wordpress.com/2019/02/06/string-pool-and-integer-pool/
https://dharashahkenya.wordpress.com/2019/02/06/string-pool-and-integer-pool/
'학습' 카테고리의 다른 글
Compile vs Interpretation (0) | 2020.07.23 |
---|---|
다형성 / Up-casting & Down-casting (0) | 2020.07.20 |
Override vs Overload (0) | 2020.07.17 |
Java Heap vs Stack (Memory Allocation) (0) | 2020.07.15 |
equals vs == (string pool) (0) | 2020.07.14 |