Back-end/이것이 자바다[신용권 한빛미디어]

Object 클래스

Ho's log 2021. 10. 22. 21:15

extends 키워드로 다른 클래스를 상속하지 않으면 암시적으로 java.Object 클래스를 상속 

자바의 모든 클래스는 Object 클래스의 자식이거나 자손 클래스


 객체 비교(equals())

public boolean equals(Object obj){...}

equals() 메소드 매개타입은 Object인데, 이것은 모든 객체가 매개값으로 대입될수 있음

-> Object가 최상위 타입이므로 모든 객체는 Object 타입으로 자동 타입 변환 될수 있다.

 

Object 클래스의 equals() 메소드는 비교연산자인 ==과 동일한 결과를 리턴

두 객체가 동일한 객체라면 true를 리턴, 그렇지 않으면 false를 리턴 

 

자바에서는 두 객체를 동등 비교할때 equals() 메소드 사용

-> 두객체를 비교해서 논리적으로 동등하면 true, 불동등하면 false 리턴

*객체의 번지수를 비교 하는게 아니라, 객체가 저장하는 데이터 동일을 비교

 

Object의 equals()메소드는 직접 사용되지 않고 하위 클래스에서 재정의하여 논리적으로 동등비교할때 이용

 

equals() 메소드를 재정의 할때 매개갑(비교 객체) 기준 객체와 동일한 타입의 객체인지 먼저 확인.

Object 타입의 매개 변수는 모든 객체가 매개값으로 제공될수 있기 때문

instanceof 연산자로 기준 객체와 동일한 타입인지 제일 먼저 확인

다른타입 -> false 반환

비교 객체 동일 타입 -> 기준 객체 타입으로 강제 타입 변환하여 필드값이 동일한지 검사

필드값이 모두 동일하다면 true 리턴, 그렇지 않으면 false 리턴 

@Override
public boolean equals(Object obj){
	if(obj instanceof 비교객체타입){
    	비교객체타입 비교객체 = (비교객체타입)Obj;
        if.(xx.equals(비교객체.xx)){
        	return trus
        }
    
    } 
    return false 
}

 


객체 해시코드(hashCode())

객체 해시코드란 객체를 식별할 하나의 정수값,

Object의 hashCode() 메소드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴

객체마다 다른값을 가지고 있음

논리적 동등 비교 시 hashCode()를 오버라이딩할 필요성 있음

HashSet. HashMap. Hashtable은 다음과 같은 방법으로 두객체가 동등한지 비교 

hashCode() 메소드가 true가 나와도 eqauls()의 리턴 값이 다르면 다른객체 

 

hashCode() 리턴값 -> (같은) equals() 리턴값 -> (true) 동등객체

|->(다름)  다른객체     (false)<-|

 

hashmap 식별키로 객체를 사용할때 hashcode() 재정의 해야 가지온다

public class KeyExample {
	public static void main(String[] args){
    //Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성
    HashMap<Key, String> hashmap = new HashMap<Key, String>();
    
    //식별키 "new Key(1)"로 "홍길동"을 저장
    hashMap.put(new Key(1), "홍길동");
    
    
    //식별키 "new Key(1)" 로 "홍길동"을 읽어옴
    String value = hashMap.get(new Key(1));
    System.out.println(value);
    
    
    
    
    }




}

 


객체 문자 정보(toString())

 

toString() 메소드는 객체의 문자 정보를 리턴

객체의 문자 정보란 객체를 문자열로 표현한 값

Object클래스의 toString() 메소드는 "클래스명@16진수해시코드"

 

Object obj = new Object();

System.out.println(obj.toString());

=> java.lang.Object@de6ced

 

Object의 toString() 메소드의 리턴값은 자바 애플리케이션에서는 값어 없는 정보

하위 클래스는 toString() 메소드를 재정의(오버라이딩)하여 간결하고 유익한 정보를 리턴

 

ex) Date 클래스의 toString() 메소드는 현재 시스템의 날짜와 시간정보를 리턴

String 클래스는  toString() 메소드를 재정의해서 저장하고 있는 문자열 리턴

 

System.out.println() 메소드는 매개값으로 객체를 주면 객체의 toString()메소드를 호출해서 리턴받아 출력

 


객체 복제(clone())

객체 복제는 원본 객체의 필드값과 동일한 값을 가지는 새로운 객체를 생성 하는 것 

객체를 복제하는 이유는 원복 객체를안전하게 보호하기위해서

신뢰하지 않는 영역으로 원복 객체를 넘겨 작업할 경우 원본 객체의 데이터 훼손 가능

복제된 객체를 만들어 신뢰하지 않는 영역으로 넘김

복제된 객체의 데이터가 훼손되더라도 원본객체는 아무런 영향을 받지 않음

안전하게 데이터를 보호 할수 있게 됨

객체를 복제하는 방법에는 얕은 복제와 깊은 복제

 

얕은 복제(thin clone)

단순히 필드값을 복사해서 객체를 복제하는 것

필드값만 복제하기 때문

- 필드가 기본 타입일 경우 값복사가 일어남

- 필드가 참조 타입일 경우 객체의 번지가 복사

 

Object의 clone() 메소드는 자신과 동일한 필드값을 가진 얕은 복제된 객체를 리턴

이 메소드로 객체를 복제하려면 원복객체는 반드시 java.lang.Cloneable 인터페이스를구현하고 있어야함 

 

메소드 선언이 없으에도 불구하고 Cloneable 인터페이스를 명시적으로 구현하는 이유는 클래스 설계자가 복제를 허용한다는 의도적 표시 

클래스 설계자가 복제를 허용하지 않는다면 Cloneable 인터페이스를 구현하지 않아도 됨 

Cloneable 인터페이스 구현하지 않으면, clone() 메소드 호출

CloneNotSupportedExcepition 예외 처리가 필요한 메소드 이기 때문  복제가 실패  

try - catch 구문이 필요하다  

 

try{

    Object obj = clone();

} catch(CloneNotSupporteExcepiton e){

 

}

 

복제 객체의 필드값이 변경되더라도 

원본 객체는 변경이 되지 않는다(기본 타입일 경우에만) 

 

깊은 복제(deep clone)

얕은 복제(thin clone)의 경우 참조 타입 필드는 번지만 복제되기 때문

원본 객체의 필드와 복제 객체의 필드는 같은 객체를 참조 

-> 얕은 복제의 단점

얕은 복제 반대 개념 깊은 복제(deep clone) 

참조하고 있는 객체도 복제하는것 

 

깊은 복제를 하려면 Object의 clone() 메소드를 재정의 해서 참조 객체를 복제하는 코드를 직접 작성 

@Override
protect Object clone() throws CloneNotSupportedException {

	//먼저 얕은 복사를해서 필드 복제
    복제객체타입 cloned = (복제객체타입)super.clone();
    
    //참조 타입 깊은 복제
    cloned.배열필드 = Arrays.copyOf(this.배열필드, this.배열필드.length);
    
   	cloned.객체 = new 객체타입(this.객체.필드);
    
    //깊은 복제된 복제객체타입리턴 
    return cloned;

}


public 객체타입 get객체(){
	객체타입 cloned = null
    
    try {
    	cloned = (Member) clone();
    
    } catch (CloneNotSupportedException e ){
    	e.printStackTrace();
    }
   	return cloned; 


}

 

복제본은 원본 객체 완전히 영향을 미치지 않는다 callByValue와 같이

 


객체 소멸자(finalize())

참조하지 않는 배열이나 객체는 쓰레기 수집기(Garbage Collector)가 힙 영역에서 자동적으로 소멸시킴

GC는 객체를 소멸하기 직전에 마지막으로 객체의 (finalize())를 실행 

소멸자는 Object의 finalize()메소드 -> 기본적으로 실행 내용이 없다

객체가 소멸되기 전에 마지막으로사용했던 자원(데이터 연결, 파일)닫고 싶거나,

중요한 데이터를 저장하고 싶은면 Object의 finalize()를 재정의 

 

*System.gc()호출 GC 가급적 빨리실행 JVM 요청 

 

호출시 쓰레기 객체를

-> 객체를 무작위로 소멸

-> 전부 소멸 X, 메모리의 상태를 보고  일부 소멸

 

finalize() 메소드가 호출되는 시점은 명확하지 않다 

->프로그램이 종료될때 즉시 자원을 해제하거나 즉시 데이터를 최종 저장 해야한다면, 일반 메소드에서 작성하고 프로그램이 종료될때 명시적으로 메소드를 호출하는  것이 좋다 

'Back-end > 이것이 자바다[신용권 한빛미디어]' 카테고리의 다른 글

System 클래스  (0) 2021.10.23
Objects 클래스  (0) 2021.10.22
java.lang 과 java.util 패키지  (0) 2021.10.22
자바 API 도큐먼트  (0) 2021.10.22
예외 처리  (0) 2021.10.22