본문 바로가기
Learning-log/JAVA

JAVA-Object Class (2022.09.06)

by why제곱 2022. 9. 6.

1. Object


Object 클래스는 java.lang 패키지에 있는 클래스이며 가장 많이 사용되는 클래스이다. 

모든 클래스의 조상이자 시조이다. Object 클래스는 필드를 가지지 않으며 11개의 메소드로 구성되어 있다.

 

 

Java에서 상속은 필수적이다. 내가 상속을 하지 않더라도 자바는 나도 모르게 Object 클래스를 자동으로 상속한다.

즉, Java의 모든 클래스는 Object를 암묵적으로 상속받아 모든 클래스가 공통으로 포함해야할 기능을 갖춘다.

 

아래부터는 Object가 가지고 있는 대표적인 메소드들에 대해 알아보자. 

 

2. toString


Object가 가지고 있는 메소드 중 객체를 문자로 표현하는 메소드.

 

toString() 메소드는 해당 인스턴스에 대한 정보를 문자열로 반환한다. 

 

보통 object class에 있는 toString을 있는 그대로 사용하면 해당 인스턴스가 어떤 클래스인지 모든 정보가 나오게 된다.

하지만 toString을 아래와 같이 오버라이딩하면 toString이 출력하는 내용을 바꿀 수 있다. 

Public String toString() {
	return "left:"+this.left+", right:"+this.right;
}

위의 예제는 수강은 유튜브 인강의 예제에서 따온 것으로 left, right는  calculator라는 class의 변수에 해당된다.

 

위와 같이 toString을 오버라이딩하여 left와 right에 각각 10,20을 입력한 후 출력하면 아래와 같은 결과를 얻게 된다.

left :10, right:20

 

이처럼 보통 toString은 오버라이딩을 통해 재정의하여 원하는 결과값을 출력하도록 사용한다.

 

3. equals


두 인스턴스를 비교하여 그 결과를 반환하는 메소드로, true or false의 결과값을 출력한다.

 

이 또한 오버라이딩을 통해 재정의하여 사용할 수 있다.

예를 들어 보통 두 객체가 다른 객체라면 false가 나오지만 그렇다 하더라도 내부적으로 같은 상태라면 true를 반환하게 재정의할 수 있다.

 

Public boolean equals(Object obj){
	Student s = (sudent)obj;
    return this.name == s.name;
 }

 

equals 내용을 오버라이딩한 과정에서 obj 변수 앞에 붙은 (student)는 부모 클래스를 자식 클래스에 대입시킬 수 없기 때문에 형변환을 위한 것이다.

 

보통 clone 은java에서 기본적으로 제공한 형태 그대로, 객체를 비교할 때 사용하기를 권장된다고 한다.

equal과 비슷한 비교연산자 == 는 원시 데이터형을 비교할 때 사용하기를 권장한다.

 

 

4. finalize


객체가 소멸될 때 호출되기로 약속된 메소드. 다른 말로 하면, 해당 객체를 더이상 아무도 참조하지 않아 소멸될 때, 가비지 컬렉터가 객체의 리소스를 정리하기 위해 호출하는 메소드.

결과적으로, 많은 java의 전문가들이 여러가지 이유로 만류하고 있다고 한다.

 

여기서 가비지 컬렉터란 메모리 절약을 위해 필요한 자바의 기능이다.

인스턴스를 만들었고 변수를 담았으나 그 변수를 더이상 사용하지 않는다면 이 변수와 변수에 담겨있는 인스턴스는 더 이상 메모리를 차지하고 있을 필요가 없어진다. 자바에서는 이를 감지하여 자동으로 쓰지 않는 데이터를 삭제하며 이를 통해  개발자가 메모리를 아끼기 위한 작업을 직접 할 필요가 없는 것이다.

 

 

 

5. clone


어떤 객체가 있을 때, 그 객체와 똑같은 객체를 복제해주는 기능을 하는 메소드

 

1)  복제가능한 Class임을 지정하기

어떤 인스턴스를 복제하기 위해서는 그 class가 복제가능한 class임을 virtual machine에게 알려줘야 한다.

따라서 그 class에 cloneable임을 지정하여 인터페이스를 구현해줘야 한다. 

Class Student implements Cloneable {
	String name;
    Student(String name) {
    	this.name = name;
 }
 
 public class ObjectDemo {
 
 	public static void main(String[] args)
    	Student s1 = new Student('yy");
       s1.clone() ;
        
 }

위 예제에서 Class Student 뒤의 "implements Cloneable" 이 들어가지 않는다면 해당 클래스가 복제가능하지 않은 상태이기 때문에  "s1.clone" 부분에서 오류가 발생하게 된다.

 

이 때, "Clobeable"이라는 인터페이스의 내용에는 아무 내용 없이 비어 있다. 그럼에도 이 Cloneable을 사용하는 이유는 Stuent class가 복제가능한 class라는 것을 알려주는 일종의 구분자 역할을 하기 때문에 사용해야 한다.

 

2) 접근제어자가 Protected ?! 

Clone을 사용하고자 하는 Class에 Cloneable 인터페이스를 구현해준 후에도 또 다른 문제가 생긴다. 바로 clone의 접근제어자는 protected 라는 것이다. Protected는 서로 다른 패키지에서는 호출할 수 없고 서로 다른 패키지에서 상속은 가능한 특징을 갖는 접근제어자이다.

해당 예제의 Class가 있는 패키지가 Object와 다른 패키지라고 하면, Clone을 호출할 수 없게 된다.

따라서 1) 예제에서 아래 예제의 중간 문단 부분을 추가하여 Student가 Object class의 clone이라는 메소드를 상속받을 수 있도록 해야한다.

Class Student implements Cloneable {
	String name;
    Student(String name) {
    	this.name = name;
 }
 
 public Object clone() {
 	return super.clone();
 }
 
 public class ObjectDemo {
 
 	public static void main(String[] args)
    	Student s1 = new Student('yy");
       s1.clone() ;
        
 }

.

 

3) Clone이 Throw한 Exception 처리하기

 

2)까지 문제를 해결해도 여전히 오류가 발생한다. Clone은 RuntimeException이 아닌 그냥 Exception이기 때문다. 즉, clone은 checked exception에 해당하여 반드시 throw된 예외를 처리해줘야하는 메소드에 속한다

 

이는 이전 게시물 내용에서와 같이 예외 처리 방법 중 하나를 택하여 예외를 처리하면 된다.

아래는 사용자에게 예외처리를 throw하는 방법으로 예외처리를 한 예이다.

 

Class Student implements Cloneable {
	String name;
    Student(String name) {
    	this.name = name;
 }
 
 public Object clone() throws CloneNotSupportedException{
 	return super.clone();
 }
 
 public class ObjectDemo {
 
 	public static void main(String[] args)
    	Student s1 = new Student('yy");
       try {
       Student s2 = s1.clone() ;
     } catch (CloneNotSupportedException e)  {
     e.printStackTrace();
   }
 }

 

 

4) 형변환 처리하기

 

3)까지 예외처리를 마쳐도 여전히 오류가 발생한다. 그 원인은 try 구문에 있다. 

s2는 Student class에 해당되지만  s1.clone은 return값이 object class에 해당된다. 따라서 s1.clone을 명시적으로 (Student)를 붙여 형변환을 해줘야한다. 

Class Student implements Cloneable {
	String name;
    Student(String name) {
    	this.name = name;
 }
 
 public Object clone() throws CloneNotSupportedException{
 	return super.clone();
 }
 
 public class ObjectDemo {
 
 	public static void main(String[] args)
    	Student s1 = new Student('yy");
       try {
       Student s2 = (Student)s1.clone() ;
     } catch (CloneNotSupportedException e)  {
     e.printStackTrace();
   }
 }

 

 

<정리>

 

- Object Class는 모든 Class의 조상이다.

- 모든 Class들은 Object가 가지고 있는 메소드들을 공통적으로 가지고 있다.

- 공통적으로 가진 메소드를 필요에 따라 오버라이딩하여 재정의해서 사용할 수 있다.

- 모든 class는 object class의 class를 데이터타입으로 가지고 있는 변수에 인스턴스화되어 담길 수 있다.

- 반대로, 데이터타입으로 object를 갖는 인스턴스를 원래 class에 대입하기 위해서는 object를 데이터 타입으로 갖는 인스턴스를 명시적으로 형변환 해야한다.

 


 

해본 게시글은 유튜브 인강을 통해 하루 동안 공부한 내용을 바탕으로 복습한 내용입니다.

내용에 오류가 있거나 보충할 내용이 있다면 댓글 남겨주시면 참고하여 수정하도록 하겠습니다.

 

유튜브 인강은 생활코딩의 Java 입문수업(생활코딩) 을 참고하였습니다.

위 게시글의 모든 예제의 출처 :  생활코딩 JAVA입문수업의 Object 클래스 중 clone 강의

자바 수업을 리뉴얼 했습니다 - YouTube