[JAVA] java.lang 패키지 [ + util classes ] (1)

DongGyu Jung·2022년 2월 6일
0

자바(JAVA)

목록 보기
23/60
post-thumbnail

🏃‍♂️ 들어가기 앞서..

본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕

*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.



" java.lang패키지 "는 가장 기본이 되는 클래스들을 포함하고 있는만큼
import문 없이 사용할 수 있다.

가장 기본이 되는만큼
자주 사용되기 때문에 해당 패키지의 여러 클래스 중
중요한 몇 가지만 알아보도록 하자.
( 별개로 자주 쓰이는 키워드들도 따로 다룰 예정이다.. )

💼 Object 클래스

Object 클래스는 상속에 대해 알아볼 때 자주 볼 수 있었는데
해당 클래스는
모든 클래스의 최고 조상이고
Object클래스의 멤버들은 모든 클래스에서 사용 가능하다.
( 오직 " 11개의 메서드 "만을 가지고 있음)

Object클래스 메서드설명
protect Object clone()객체 자신의 복사본을 반환
( public으로 오버라이딩 해줘야함. )
public boolean equals( Object obj )객체 자신 - 객체 obj가 같은 객체인지 알려준다.
( 같으면 true )
protect void finalize()(거의 사용 X) " 객체가 소멸될 때 " 가비지 컬렉터에 의해 자동적으로 호출
( public으로 오버라이딩 해줘야함. )
public Class getClass()객체 자신의 클래스 정보를 담고있는 Class 인스턴스 반환
public int hashCode()객체 자신의 해시코드 반환
public String toString()객체 자신의 정보를 문자열로 반환
public void notify()객체 자신을 사용하려고 기다리는 쓰레드(Thread)" 하나만 " 깨움.
public void notifyAll()객체 자신을 사용하려고 기다리는 " 모든 " 쓰레드(Thread)를 깨움.
public void wait()
public void wait( long timeout )
public void wait(long timeout, int nanos)
위 notify메서드들을 다른 쓰레드가 호출할 때까지
현재 쓰레드를 " 무한히 / 지정된 시간 (timeout , nanos)동안 " 기다리게 한다.
( timeout : 1/1000 초 , nanos : 1/10^9 초 )


🔎 equals() 메서드

/*
실제 Object클래스에 정의되어 있는 equals 메서드
*/
public boolean equals(Object obj) {
    return (this==obj);
}

매개변수로
" 객체의 참조변수 "를 받아서 비교한 후,
boolean값 결과를 반환한다.

단,
주의해야할 점은
equals()메서드는
엄밀히 말하자면
" 두 인스턴스의 주소값(참조변수 값)으로 비교 "를 하기 때문에

보이는 값은 같을지라도
결과가 false가 나올 수도 있다.

equals() 오버라이딩

해당 메서드는 두 주소값만을 비교하고 이외에 판단하지 않는다.
그래서
주소값이 아닌 을 비교할 수 있도록 하기위해
오버라이딩이 필요하다.

즉,주소가 아닌
객체에 저장된 내용을 비교하도록 변경하는 것이다.

class Test {
    public static boid main(String[] args) {
    Value v1 = new Value(10) ;
    Value v2 = new Value(10) ;
   
    if (v1.equals(v2))
        System.out.println( " 둘이 똑갔습니다.");
    esle
        System.out.println( " 둘이 다르다. ");
}
class Value {
    int value ;
   
    Value(int value) {
        this.value = value ;
    }
   
    // Object의 equals() 오버라이딩
    // 형전환 전엔 반드시 instanceof 로 확인
    public boolean equals(Object obj) {
        if(!(obj instanceof Value)) return false ; // 
      
        Value v = (Value)obj ; // value로 형변화
        return this.value == v.value ;
    }}
}

하나 더 살펴보자면

class Person {
	long id;

    public boolean equals(Object obj) { //equals() 오버라이딩 _ id값을 비교하도록 만듦
    	if(obj instanceof Person)
        	return id == ((Person)obj).id // Object타입이기 때문에 Person타입으로 형변환하여 id값 참조
        else
        	return false ;
    }

    Person(long id) { //주민번호를 매개변수로 받는 
    	this.id = id;
    }
}

class Program {
	public static void main(String[] args) {
		Person p1 = new Person(8008081111222L);
        Person p2 = new Person(8008081111222L); 
        /*
        만약 오버라이딩을 하지 않았다면
        p1의 객체 주소값과 p2의 객체 주소값을 비교하게되서
        false가 반환됨.
        */

        if(p1.equals(p2)) // 오버라이딩해서 주소값을 비교하는것이 아닌 id를 비교하게됨.
        	System.out.println("같은 사람") ;
            // 서로 같은 8008081111222 값의 메모리 주소를 가지고있기 때문에 true가 출력된다.
        else
        	System.out.println("다른 사람") ;
    }
}


🔎 hashCode() 메서드

" 해싱(hashing) 기법 "에 사용되는 【해시함수(hash function)】을 구현한 것
(데이터 관리 기번 중 하나 _ 다량의 데이터 저장&검색에 유용)

Object클래스의 hashCode()는 " 객체의 주소int로 변환해서 반환 "

정확히 말하자면
객체의 주소값을 이용해서 해시코드를 만들어 반환하는 것이다.
따라서
" 서로 다른 두 객체는 절대 같은 해시코드를 가질 수 없다 "는 특징이 있다.

이 특징을 통해
" 객체의 같고 다름을 확인해야하는 경우 "

같은 객체라면
hashCode()의 결과값, 해시코드가 같아야 한다는 것 을 활용해야 한다.

그렇기 때문에
앞서 알아본 equals()메서드를 오버라이딩 한다면
hashCode() 메서드도 오버라이딩해서 사용해야 한다.
( 오버라이딩을 하지않으면 본래 정의된 대로 모든 객체가 다른 해시코드를 갖게 됨. ▶ equals는 true가 나오는데 hashCode가 다르면 모순 )


단,
String 클래스는 " 문자열 내용이 같으면 "
동일한 해시코드를 반환하도록 본 메서드가 오버라이딩되어 있다.

아래 코드를 살펴보면 알 수 있지만
String클래스 객체인 str1str2의 해시코드는 같지만
서로 다른 객체라는 것을 알 수 있다.

String str1 = new String("abc");
String str2 = new String("abc");

System.out.println(str1.equals(str2)) ; // true를 반환
/*
String 클래스에는 오버라이딩이 되어있기 때문에
두 hashCode() 반환값이 동일함
*/
System.out.println(str1.hashCode()) ; 
System.out.println(str2.hashCode()) ; 

// 단, 위 str1, str2 가 String클래스더라도 
// Object클래스의 hashCode()와 같이 객체의 주소값으로 해시코드를 생성하는 메서드가 있다.
// System.identityHashCode(Object x)
/*
두 반환값이 다르다.
(오버라이딩하기 이전의 기능이 필요할 때 사용)
*/
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));


🔎 toString() 메서드

" 인스턴스에 대한 정보문자열로 제공할 목적으로 정의된 메서드 "
※ 기본적 Object클래스 내 정의된 toString()

public String toString() {
	return getClass().getName()+"@"+Integer.toHexString(hashCode());
    // [클래스이름]@[16진수 해시코드 _ 객체주소]
}

위에 나온 16진수 해시코드는
hashCode()를 오버라이딩 하지 않는다면
같은 클래스 객체더라도
각 객체마다 다른 toString() 출력하게 될 것이다.

toString() 오버라이딩

물론 16진수 해시코드가 필요하다면 사용할 수 있겠지만
사실 큰 효용성은 없다고 볼 수 있다.

따라서
우리가 알고 싶은 " 멤버들에 대한 정보 "를 출력하게끔 오버라이딩을 할 수 있다.
예를 들면

public String toString() {
	return "(멤버변수 a) : " + (멤버변수 a) + "(멤버변수 b) : "+ (멤버변수 b) ;
}

여기서 조심해야 할 것은
전부터 누누히 강조되어왔지만
" 오버라이딩의 조건 " 중
조상클래스의 접근제어자보다 같거나 넓어야 한다는 점 을 명심해야한다.
(위를 보면 Object클래스에 정의된 toString()메서드의 접근제어자는 public이기 때문에
오버라이딩할 때, 동일하게 public으로 해야한다.)

0개의 댓글