Java.lang패키지
- java.lang패키지는 자바프로그래밍에 가장 기본이 되는 클래스를 포함하고 있어서 java.lang패키지의 클래스들은 import문 없이도 사용가능함
Object클래스
- 모든 클래스의 최고조상으로 11개의 메서드만을 가지고 있다.
- protected는 오버라이딩해서 public으로 변경해야 사용할 수 있음!(아니면 작성한 클래스의 자손클래스나 같은 패키지에서만 사용 가능하기 때문)
- public Class getClass( ) 객체의 클래스 정보(설계도 정보)를 반환
-> 이 설계도 객체를 통해서 1) 객체 생성 2) 객체 정보 얻을 수 있음
- notify( ), notifyAll( ), wait( )은 쓰레드(thread)와 관련된 것들이며, 나중에 쓰레드에서 자세히 설명!
equals(Object obj)
- 객체 자신(this)과 주어진 객체(obj)를 비교한다.
- 반환타입 boolean이라서 같으면 true, 다르면 false
- object클래스의 equals( )는 객체의 주소를 비교(매개변수로 객체의 참조변수를 받아서 비교) -> 서로 다른 두 객체를 equals 메서드로 비교하면 항상 false를 결과로 얻게 됨!
- 인스턴스의 값(내용)을 비교하려면(주소가 아닌) equals( )메서드를 오버라이딩 해야함!
equals의 기본형
public boolean equals(Object obj) {
return (this==obj); // 주소 비교
}
Value v1 = new Value(10);
Value v2 = new Value(10);
System.out.println(v1.equals(v2)); //false
class Value {
int value;
Value(int value) {
this.value = value;
}
}
- 서로 다른 두 객체는 항상 주소가 다르다!
예제1) 객체(참조변수)의 주소가 아니라 iv값을 비교하도록 equals()를 오버라이딩 Value클래스를 생성하고 value 인스턴스 변수를 가지는 생성자를 만들고 equals를 오버라이딩
public class Ex9_1 {
public static void main(String[] args) {
Value v1 = new Value(10);
Value v2 = new Value(10);
if(v1.equals(v2))
System.out.println("v1과 v2는 같습니다.");
else
System.out.println("v1과 v2는 다릅니다.");
} // main
}
class Value {
int value;
Value(int value) {
this.value = value;
}
// value의 조상인 Object의 equals를 오버라이딩해서 주소가 아닌 value를 비교
public boolean equals(Object obj) {
// 참조변수의 형변환 전에는 반드시 instanceof로 확인해야 함
if(!(obj instanceof Value)) return false;
// obj를 value로 형변환(Value 클래스에는 value가 있지만 Objcet클래스에는 없기 때문)
Value o = (Value)obj;
return this.value == o.value;
}
//equals의 기본형
// public boolean equals(Object obj) {
// return (this==obj); // 기본형은 주소 비교. 서로 다른 객체는 항상 거짓
// }
}
<출력값>
v1과 v2는 같습니다.
예제2) 객체(참조변수)의 주소가 아니라 iv값을 비교하도록 equals()를 오버라이딩. Person 클래스를 생성하고, long타입의 주민번호 iv를 생성한 뒤에 equlas메서드 오버라이딩!
public class Ex9_2 {
public static void main(String[] args) {
Person p1 = new Person(123456789L);
Person p2 = new Person(123456789L);
System.out.println(p1.equals(p2));
if(p1==p2) { // 객체(주소값)비교
System.out.println("p1과 p2는 같습니다.");
} else {
System.out.println("p1과 p2는 다릅니다.");
}
if(p1.equals(p2)) { // iv값 비교
System.out.println("p1과 p2는 같습니다.");
} else {
System.out.println("p1과 p2는 다릅니다.");
}
}
}
class Person {
long id;
Person(long l) { // 생성자
this.id = l;
}
public boolean equals(Object obj) {
if (obj instanceof Person) //obj가 Object타입이므로 id값을 참조하려면 Person타입으로 형변환 필요
return id == ((Person)obj).id;
else
return false; // 타입이 Person이 아니면 값을 비교할 필요도 없다.
}
}
<출력값>
true
p1과 p2는 다릅니다.
p1과 p2는 같습니다.
p1 == p2 -> 0x100 == 0x200 -> false (오버라이딩 하지 않으면 객체를 가르키는 주소로 비교)
p1.equals(p2) -> this.id = ((Person)obj).id -> 8011081111222L == 8011081111222L -> true
hashCode( )
- 객체 주소값으로 해시코드(hash code)를 반환하는 메서드
- 이 메서드는 해싱(hashing)기법에 사용되는 ‘해시함수(hash function)’을 구현한 것
- 해싱(데이터관리기법 중 하나)은 다량의 데이터를 저장하고 검색하는데 유용
- 해시함수: 찾고자 하는 값을 입력 -> 그 값이 저장된 위치를 알려주는 해시코드(hash code)반환
- Object클래스의 hashCode( )는 객체의 주소를 int로 변환해서 반환(객체마다 각각의 값을 가짐)
- 해시코드 => 정수 값(객체의 지문이라고도 함: 객체마다 다른 값을 가져서)
public class Object {
...
public native int hashCode() ; // 내용 xx
}
native(네이티브메서드): OS의 메서드(C언어)
-> 이미 작성 되어있는 메서드를 호출하기 때문에 내용이 없음
-> C언어로 작성되어서 안의 내용을 볼 수 없음
- equals( )를 오버라이딩하면, hashCode( )도 오버라이딩해야 한다. (equals와 hahCode 둘 다 객체의 주소를 가지고 작업) -> equals가 iv를 가지고 작업을 한다면 hashCode도 iv를 가지고 작업!
- equals의 결과가 true이면 두 객체의 해시코드는 같아야 하기 때문
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2)); // true
System.out.println(str1.hashCode()); // 96354
System.out.println(str2.hashCode()); // 96354
System.out.println(System.identityHashCode(str1)); //1694819250
System.out.println(System.identityHashCode(str2)); //1365202186
-> String클래스는 문자열의 내용이 같으면, 동일한 해시코드를 반환하도록 hashCode메서드가 오버라이딩 되어 있음!(그래서 문자열 str1과 str2에 대해 hashCode( )를 호출하면 동일한 해시코드 값을 얻음)
-> System.identityHashCode(Object obj)는 Object클래스의 hashCode( )와 동일(주소값을 사용하기때문에 모든 객체에 대해 항상 다른 해시코드값을 반환함)
toString( )
- toString( ): 객체를 문자열(String)으로 변환하기 위한 메서드
- 객체 == ‘iv 집합’ 이므로 객체를 문자열로 변환한다는 것은 iv의 값을 문자열로 변환한다는 것과 같다.
- 클래스를 작성할 때 toString()을 오버라이딩하지 않으면, Card@4b8cfb5 이렇게 출력됨!(16진수의 해시코드)
- 오버라이딩 할 때 문자열의 결합을 사용해서 iv값 이용
예제1) Card클래스에서 멤버변수인 kind와 number를 생성하고 toString을 오버라이딩
public class Ex9_4 {
public static void main(String[] args) {
Card c = new Card();
// System.out.println(c.to()); // to 메서드를 출력 결과값은 동일함
System.out.println(new Card());
System.out.println(c);
System.out.println(c.toString());
}
}
class Card {
String kind;
int number;
Card() {
this("SPADE", 1); //생성자로 kind와 number 초기화
}
Card(String k, int num) {
this.kind = k;
this.number = num;
}
//오버라이딩 하려면 선언부 같아야 함
public String toString() { //Card인스턴스의 kind와 number를 문자열로 반환
return "Kind: " + kind + ", number: " + number;
}
// public String to() { // to( ) 메서드
// return "Kind: " + kind + ", number: " + number;
// }
}
<출력값>
Kind: SPADE, number: 1
Kind: SPADE, number: 1
Kind: SPADE, number: 1
예제2) 예제1 + equals와 HashCode 오버라이딩 하기!
import java.util.Objects;
public class Ex9_4 {
public static void main(String[] args) {
Card c = new Card();
Card c2 = new Card();
System.out.println(new Card()); // kind: STAR, number: 6
System.out.println(c.equals(c2)); // true
System.out.println(c.hashCode()); // -1842861219
System.out.println(c2.hashCode()); // -1842861219
}
}
class Card {
String kind;
int number;
Card() {
this("STAR", 6);
}
Card(String k, int num) {
this.kind = k;
this.number = num;
}
//Object클래스의 toString을 오버라이딩 선언부는 그대로!!
public String toString() {
return "kind: " + kind + ", number: " + number;
}
// equals 오버라이딩
public boolean equals(Object obj) {
if(!(obj instanceof Card))
return false;
Card c = (Card)obj;
return kind.equals(c.kind) && this.number == c.number; //kind는 string이어서 equals
// return this.kind.equals(((Card)obj).kind) && this.number == ((Card)obj).number;
}
// equals()를 오버라이딩하면 hashCode()도 오버라이딩 해야한다.
public int hashCode() {
return Objects.hash(kind, number); // hash가 가변인자라서 호출시 지정하는 값의 개수 정해져 있지 않음
}
}
-> hashCode의 오버라이딩 코드에서 Objects클래스는 객체와 관련된 유용한 메서드를 제공하는 유틸 클래스
'멀티캠퍼스 풀스택 과정 > Java의 정석' 카테고리의 다른 글
자바의 정석6-3 Math클래스, Rapper클래스, Number클래스 (0) | 2022.01.07 |
---|---|
자바의 정석6-2 String 클래스, Stringbuffer(StringBuilder) (0) | 2022.01.07 |
자바의 정석5-3 사용자 정의 예외, 예외 되던지기, 연결된 예외 (0) | 2022.01.06 |
자바의 정석5-2 예외 발생, 예외 처리, Finally블럭 (0) | 2022.01.06 |
자바의 정석5-1 예외처리(exception handling) (0) | 2022.01.06 |