byte : 8 bits
short : 16bits
int : 32bits
long : 64 bits
float : 32bits
double : 64bits
boolean : 1 bit
char : 16 bits
위 데이터 타입들은 전부 primitive type이라 불리며, Wrapepr class가 존재한다.
byte - Byte
short - Short
int - Integer
long - Long
float - Float
double - Double
boolean - Boolean
char - Character
자바에서 primitive type은 딱 위의 8개이다.
다만, String은 문법적으로는 primitive type처럼 편리하게 쓸 수 있지만, 엄연히 'Object'이다. String class이다!
-> 즉, 'String은 primitive type처럼 편하게 쓸 수 있는 Objeect이다.' 가 맞는 표현.
int x = Integer.parseInt("1234");
위 코드는 최종적으로 x라는 int primitive type 변수에 담기기 때문에, 함수 리턴값에 관계없이 int형으로 언박싱되는건가?
=> 애초에 Integer.parseInt() method는 static이며, 리턴 형태가 int다. 따라서 언박싱이 일어나지는 않고 있다.
그렇다면 Wrapper class는 대부분 static method들로 이뤄져있겠네?
=> 아니다. 객체 생성없이 바로 호출 가능해야 하는 '유틸리티' 성격의 메소드들은 static이 맞지만, Wrapper 객체가 가진 내부 primitive 값을 꺼내는 method들은 instance method이다. 따라서 static일 수 없다.
// Wrapper class code example
int x = 25;
Integer y = new Integer(33); // 교수님.. 이 constructor는 Eclipse ver.9 부터 사라졌대요...
int z = x + y; // wrong! ... 이것도 최신 이클립스에서는 잘 돌아감.
int z = x + y.intValue(); // OK!
char[] hArr = {'h', 'e', 'l', 'l', 'o', '.'};
String hStr = new String(hArr);
System.out.println(hStr); // hello.
신기하다. char 배열을 주면 자동으로 이어붙여준다.
왜 그런가?
public String(char[] value) {
this(value, 0, value.length, null);
}
...
String(char[] value, int off, int len, Void sig) {
if (len == 0) {
this.value = "".value;
this.coder = "".coder;
return;
}
if (COMPACT_STRINGS) {
byte[] val = StringUTF16.compress(value, off, len);
if (val != null) {
this.value = val;
this.coder = LATIN1;
return;
}
}
this.coder = UTF16;
this.value = StringUTF16.toBytes(value, off, len);
}
아... 자동으로 이어붙여준 게 아니라, 어쨌든 String object 내부에 이 hArr 값들을 전부 하나하나 원소로 갖고 있다가, print를 할 때 String method중 'toString()'이 이 원소들을 한 줄로 합쳐 보여주는 것이다.
마치 join이나 concat를 한 것처럼 보이지만, 사실은 단순한 배열 복사 + 출력 규칙이었던 것.
"My name is ".concate("John");
따로 String constructor를 쓰지 않아도 String class의 method를 사용할 수 있다는 건, 이 큰 따옴표가 뭔가 자동으로 String object를 만들어내는 약속을 의미한다는 건가?
=> 이런 따옴표 문자열은 컴파일 타임에 이미 String 객체로 변환된다. 즉, 자바 컴파일러가.class를 만들 때, 그 객체를 String Pool에 올려둔다. 그래서 별도의new없이 곧바로 쓸 수 있는 것.
What is String Pool?
JVM은 같은 리터럴 "Hello"가 여러 번 등장해도 하나의 String 객체만 만들어서 공유한다.String a = "Hello"; String b = "Hello"; System.out.println(a == b); // true (같은 객체)
String c = new String("Hello");
System.out.println(a == c); // false
String d = new String("Hello");
System.out.println(c == d); // false
>String Literal ("...") 로 선언한 것들은 String Pool에 올라가며, 같은 문자열을 선언하게 되면, 하나의 객체를 공유하여 참조할 때도 같은 곳을 참조하게 된다.
반면, new String과 같이 `new`로 선언할 경우, 무조건 Heap에 새 객체를 생성하기 때문에, 같은 문자열을 선언해도 다른 객체로 인식한다.
>
`==`로 비교하는 건 '참조(주소) 비교'
`.equals()`로 비교하는 건 '값(문자열 내용) 비교'이다!
그래서 후자로 검증할 경우 a, b, c, d 모두 동일한 값을 가지므로 true.