자바 프로그래밍에 가장 기본이 되는 패키지
Import 없이 사용 가능
객체의 참조변수(주소)를 받아 비교하여 결과를 반환
위에 코드를 보았을 때, equals 메서드가 주소값을 비교하는 기능만 수행하는 것을 알 수 있다. 주소 말고 값을 비교하는 방법은 ? → 오버라이딩
equals 메서드를 오버라이딩 하여, instanceof를 사용하여 형변환이 가능한지 확인하고 True일 경우 객체의 주소가 아닌 값을 참조하기 위해 형변환을 수행
해싱 기법에 사용되는 해시함수
값을 입력하면 그 값이 저장된 위치를 알려주는 해시코드를 반환
같은 객체일 경우 해시코드가 같다.
📌 이해 안가는 부분
hashCode는 같은 문자열이면 True 반환
identityHashCode는 같은 객체면 True 반환
인스턴스를 복사하여 새로운 인스턴스 생성
원래 인스턴스는 보존되기 때문에 복사한 인스턴스를 수정하다가 오류가 날 경우 원래 상태로 돌아가는데 사용
값만 복사하기 때문에 복사된 인스터스와 영향을 주지 않는다.
💡 배열을 복사할 경우, 배열은 같은 주소를 같기 때문에 영향을 준다. 배열은 clone할 때는 Clone을 오버라이딩 해야한다.
📌clone()을 사용하려면 다음과 같은 요소가 필요하다.
- Cloneable 인터페이스 구현
→ 인터페이스를 구현해야 clone() 호출 가능
→ 인스턴스의 데이터를 보호하기 위해서- 접근제어자를 protected에서 public으로 변경
→ 상속관계가 없는 다른 클래스에서 clone 호출을 위해- clone()을 호출하는 코드가 포합된 try-catch문 작성
→ clone은 반드시 예외처리 필요
조상 메서드의 반환타입을 자손 클래스의 타입으로 변경 허용
public Object clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
}
return obj;
}
public Point clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
}
return (Point)obj;
}
공변반환 타입을 사용해 clone 메서드를 오버라이딩 하면, 번거로운 형변환을 줄일 수 있다.
얕은 복사: 복사된 것이 같은 객체를 공유하여 서로 영향을 주는 복사
깊은 복사: 객체까지 완벽히 복사하여 서로 다른 객체를 참조하는 복사
✏️ Shallow Copy
clone으로 c1을 복제해 c2를 생성할 경우, 같은 Point를 참조
✏️ Deep Copy
얕은 복사와 달리, 복제된 객체가 새로운 Point 인스턴스를 참조하도록 했다.
obj를 Cirecle로 형변화 후 새로운 Point 객체를 생성
클래스가 속해있는지 찾는 메서드
✓클래스 로더: 실행시에 필요한 클래스를 동적으로 메모리에 로드하는 역할
Java의 문자열을 다루는 매우 중요한 클래스
변경하지 않는 클래스로, 한번 생성된 String 인스턴스가 갖고 있는 문자열은 읽어만 오고, 변경은 불가능하다.
Stirng a = "a";
String b = "b";
a = a + b;
위의 코드를 봤을 때, a가 ab로 변경되는 것이 아닌, immutable을 성격상 ab라는 새로운 객체가 생성 되는 것
따라서, 문자열 결합(+)은 새로운 객체를 생성하는 연산으로 메모리 공간을 차지 하기 때문에 최대한 사용을 줄이는 것도 중요
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");
str1과 str2는 이미 존재하는 주소를 저장하는 것이기 때문에 str1과 str2는 같다.(재사용)
하지만 str3,str4는 새로운 객체를 생성하여 메모리를 할당한 것이 떄문에 서로 다른 주소를 같는다.
📌주의
== : 주소 비교
equals: 내용 비교
문자열 리터럴도 String 인스턴스로 한번 생성하면 변경 불가
s1,s2,s3가 동일한 AAA를 참조
String s1 = "AAA";
String s2 = "AAA";
String s3 = "AAA";
유니코드의 보충문자
유니코드는 원래 16비트의 문자체계인데, 20비트로 확장하여 하나의 문자를 char 타입으로 다루지 못해 int로 다루는 것
인코딩 변환
문자열의 문자 인코딩을 다른 인코딩으로 변경
서라 다른 문자 인코딩을 사용하는 컴퓨터 간에 데이터를 주고 받을 때 사용
📌 이 부분도 한번 봐볼 필요가 있다고 생각한다.
int i = 100; // 정수
String str1 = i + ""; //숫자를 문자열로 변환하기 위해 빈문자열 추가
String str2 = String.valueOf(i); // valueOf 사용
//반대
int i = Integer.parseInt("100");
// 💡parseInt를 한번 더 봐보자
// 문자열에 공백 또는 문자가 포함되어 있는 경우는 변환시 예외가 발생할 수 있다.
// 그러므로 trim()을 사용해 양끝의 공백을 제거하는 습관
int i2 = Integer.valueOf("100");
빈문자열을 추가하는 방법이 간단하지만, 성능향상이 필요할 때에 valueOf 사용
(빈문자열을 사용한 결합은 메모리를 증가! 앞서 배움!)
String과 비슷하지만 알아야 될게 몇 가지 있어서 보고 간다.
String과 다르게 문자열을 변경할 수 있고, 크기를 지정할 수 있다.
이때 버퍼의 크기를 충분히 잡아야 하며, 그렇지 않을 경우 버퍼를 늘려주는 작업을 추가로 해야하므로 작업 효율이 떨어진다.
버퍼의 크기가 작업하려는 문자열 길이보다 작을 경우 내부적으로 버퍼를 증가시키는 작업을 수행하는데, 배열의 길이는 변경이 불가능하므로, 새로운 길이의 배열을 생성한 후에 이전 배열 값을 복사한다.
이 작업을 추가로 수행하기 때문에 효율성을 고려할 필요가 있다.
String은 등가연산자, equals 메서드가 다른 동작을 하지만,
StringBuffer는 equals를 오버라이딩 하지 않아 같은 동작을 한다.
즉 내용을 비교하는 것이 아닌 참조 주소만을 비교 가능하다.
내용을 비교하기 위해서는 toString을 사용해 인스턴스를 얻은 후 비교할 수 있다.
StringBuffer는 멀티쓰레드에서 안전하도록 동기화 되어 있다.
이 말은 즉, 멀티 쓰레드 프로그램이 아닌 경우, StringBuffer의 동기화는 불필요하게 성능을 떨어트린다.
→ StringBuilder에서 쓰레드의 동기화만 뺀 것이 StringBuilder
기본형(int, float, 등등)을 객체로 다룰 때 필요한 클래스 (Integer가 Wrapper)
생성자의 매개변수는 반드시 각 자료형에 맞는 문자열을 사용해야 한다.new Integer(1); new Integer("1.0"); //error!
parseInt: 반환값이 기본형
valueOf: 반환값이 래퍼
parseInt가 더 성능이 좋다
형변환 할 때 컴파일러가 자동으로 코드를 추가해 준다.
오토박싱: 기본형 → 객체
언방식: 객체 → 기본형