DS Lec.2 - Java Basics 1

Nitroblue 1·2025년 9월 29일

자료구조

목록 보기
6/15

Data Types

byte : 8 bits
short : 16bits
int : 32bits
long : 64 bits
float : 32bits
double : 64bits
boolean : 1 bit
char : 16 bits

Wrapper class

위 데이터 타입들은 전부 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!

String

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.

0개의 댓글