20. String 클래스
String 클래스와 new 인스턴스에 대해 알아가보자.
String
문자열을 다루는 자바 내장 클래스
- String은 new~ 로 만들어지느냐 “” 문자열 리터럴로 만들어지느냐에 따라 다르게 동작된다. 확인해보자.
new~
Heap에 새롭게 생성하는 모든 String 인스턴스는 동일한 내용을 가지고 있어도 다른 객체이다.
1
2
3
String s1; // JVM Stack
s1 = new String("Hello"); // Heap
String s2 = new String("Hello"); // JVM Stack -> Heap
문자열 리터럴
String 상수 풀에 인스턴스를 생성하고 만약 같은 문자열의 인스턴스가 있다면 중복되게 만들지않는다
1
2
3
String s1;
s1 = "Hello";
String s2 = "Hello";
intern( )
인스턴스를 String pool에 생성한다. 상수 풀에 동일한 문자열이 있다면 기존 것을 사용한다.
1
2
3
String s1 = new String("Hello"); // Heap에 인스턴스 생성
String s2 = s1.intern(); // String pool에 인스턴스 새로 생성
String s3 = "Hello"; // String pool에 s2에서 만든 "Hello" 문자열 존재로 해당 인스턴스 부여
다형적 변수와 형변환
1
2
3
4
5
Object obj = new String("test");
obj.메서드 // -----------------> Object의 메서드 사용 가능. but String 메서드는 사용 불가능
String s = (String) obj; // -> Object를 강제 형변환.
s.메서드 // -------------------> String의 메서드 사용가능
((String)obj); // -----------> 한번만 사용한다면 이렇게도 사용 가능하다.
new String(byte 배열)
1
2
3
4
5
byte[] bytes =
{(byte) 0xb0, (byte) 0xa1, (byte) 0xb0, (byte) 0xa2, 0x30, 0x31, 0x32, 0x41, 0x42, 0x43};
// 문자 코드 값이 저장된 바이트 배열로 String 인스턴스 생성
String s4 = new String(bytes);
System.out.printf("s4=%s\n", s4);
byte 배열을 String에 넣었을 때 » 출력 시 글씨가 깨져 노출된다
why?
JVM이 해당 코드를 변환할때는 file.encoding(JVM 프로퍼티)에 따라 인식 후 UTF 16BE 변환하여 String 인스턴스를 생성하게 되는데..
Eclipse IDE는 클래스를 실행할 때 -D file.encodeing = UTF-8로 JVM 프로퍼티를 설정하게된다.
결국 byte 배열 값을 UTF-8 문자 코드라고 가정을 하고 변환하기 때문에 맞지않는 한국어는 깨져 노출된다.
wrapper 클래스
- primitive data type에 대응하여 만든 클래스를 primitive data를 포장하는 객체라고 해서 wrapper 클래스로 불림
wrapper 클래스 종류
- Byte > byte
- Short > short
- Integer > int
- Long > long
- Float > float
- Double > double
- Boolean > boolean
- Character > char
1
2
3
int i = 100; // 그냥 값 100
Integer obj = Integer.valueOf(i); // Integer라는 클래스에 100이라는 값을 가진 객체.
int i2 = obj.intValue(); // 그냥 값 100
primitive data type 값을 wrapper 클래스에 넣는 걸 boxing 이라하고
wrapper 클래스에서 값을 빼와 primitive data화 시키는걸 unboxing이라고 한다.
이런 작업이 귀찮고 불편한데…. 이를 자바에서 auto로 지원해준다. 오토박싱, 오토 언박싱이라고 한다.
1
2
Integer obj = 100; // ==> Integer.valueOf(100) autoBoxing 수행
int i = obj; // ==> obj.inValue() autoUnboxing 수행
대신 이를 수행하는건 JVM이 아닌 컴파일러에서 수행한다.
미니 프로젝트(myapp)
배열 크기를 자동으로 증가 시키자
배열은 메모리 크기가 고정이 되고 변경 할 수 없다.
그렇다면.. 그 이상의 값을 보관해야될 때는 어떻게 해야하는가…..?
간단하다. 기존 배열보다 큰 배열을 만들어 주고 값을 복사해서 넣으면 된다. (직접해보자)
LinkedList 자료구조
- 배열 방식
- 장점 : 메모리 크기 고정됨
- 단점 :
- 메모리 크기를 늘릴 수 없다. → 늘리기 위해서 새 배열 생성 후 기존 값 복사해야함 → 가비지 다량 발생.
- 삽입, 삭제 시 항목의 값을 밀고 당겨야하기 때문에 실행 속도가 떨어짐
- Linked List 방식
- 장점 :
- 메모리를 늘리기 쉽다
- 삽입, 삭제가 쉽다
- 단점 : 데이터 조회 시 시간이 많이 소요된다.
- 장점 :
→ 배열의 단점들을 보완하기 위해 myapp에서 Linked List 방식으로 데이터를 저장할 예정
LinkedList 구동 원리
상속의 한계
상속을 받은 모든 클래스들을 고쳐야하는 상황이 올지도 모른다. 이를 보완하기 위해 인터페이스를 사용한다. 인터페이스는 다음 글에서 상술할 예정이다.