[스터디]Java의 정석 16일차

Kristopher·2022년 1월 11일
0

Java 스터디

목록 보기
16/31

(CH9) 1. java.lang 패키지 ~

1.3 SpringBuffer클래스와 StringBuilder클래스

Object클래스

Object클래스는 모든 클래스의 최고 조상이기 때문에 머돈 클래스에서 바로 사용할 수 있다. Object클래스에 존재하는 몇몇 메소드에 대해 살펴보자.

Method of Object classDescription
protected Object clone()객체 자신의 복사본을 반환
public boolean equals (Object obj)객체 자신과 obj가 같은 객체인지 확인
public Class getClass()객체 자신의 정보를 담고 있는 class인스턴스 반환
public int hashCode()객체 자신의 해쉬코드 반환
public String toString()객체 자신의 정보를 문자열로 반환

equals(Object obj)

매개변수로 객체의 참조변수를 받아 비교하여 그 결과를 boolean값으로 알려준다. 실제 코드에서 이해해보자.

class Value{
    int value;
    
    Value(int value){
        this.value = value;
    }
}

class Equal_ex {
    public static void main(String[] args) {
        Value v1 = new Value(10);
        Value v2 = new Value(10);
        
        if(v1.equals(v2)) // false가 반환
            System.out.println("v1과 v2는 같습니다.");
        else
            System.out.println("v1과 v2는 다릅니다.");
        v2 = v1;
        
        if(v1.equals(v2)) //true가 반환
            System.out.println("v1과 v2는 같습니다.");
        else
            System.out.println("v1과 v2는 다릅니다.");
    }
}

위의 코드를 실행시켜보면 첫번째 if문은 false가 나온다. 그 이유는 v1,v2에 각각 다른 객체를 생성하였기 때문에 참조변수 v1,v2가 가리키는 대상이 다르기 때문이다. 즉 equals는 객체의 주소를 비교하여 두 객체가 다르다고 결과값을 반환한다.

"v2 = v1;"을 실행한 이후에는 v2에 v1의 주소값을 저장하기 때문에 v1과 v2가 같은 주소값을 가지고 있기 때문에 두번째 if문을 true로 반환하게 된다.

만약 각 객체가 가리키고 있는 값을 비교하고 싶다면 equals 메소드를 오버랑이딩 하여 주소값이 아닌 객체에 저장된 내용을 비교하게 할 수 있다.

public boolean equals(Object obj){
    if(obj instanceof Person) // 포함관계 확인
        return id == ((Person)obj).id; // id값을 참조하기 위해 형변환
    else
        return false;
}

hashCode()

데이터관리기법 중 하나인 해싱기법에 사용되는 해싱함수를 구현한 메소드이다. 객체의 주소값을 해시코드로 변환하여 반환하기 때문에 32bit JVM에서는 같은 해시코드가 발생할 수 없었지만, 64bit JVM에서는 8byte 주소값으로 해시코드를 만들기 땜누에 해시코드가 중복될 수 있다.

toString()

toString() 메소드는 인스턴스에 대한 정보를 문자열로 제공할 목적으로 정의한 것이다. 인스턴스의 정보란 인스턴스 변수에 저장된 값들을 문자열로 표현한 것이다. toString()을 오버라이딩 하지 않은채 사용하면 '클래스 이름@16진수의 해시코드' 형태를 얻을 것이다. 인스턴스의 정보를 문자열로 받고 싶다면 toString() 메소드가 적절히 오버라이딩 되어있는 클래스를 import하여 사용하거나 직접 오버라이딩하여 형태를 지정해야 한다.

clone()

clone()은 자신을 복제하여 새로운 인스턴스를 생성하는 일을 한다. 단순히 인스턴스변수의 값만을 복사하기 때문에 참조타입의 인스턴스 변수가 있는 경우(ex. 배열)에는 완전한 인스턴스의 복제가 이루어지지 않는다.

복사의 종류에는 얕은 복사와 깊은 복사가 존재한다. clone()은 단순히 객체에 저장된 값만을 복제할 뿐, 객체가 참조하고 있는 객체는 복사하지 않는다. 객체 배열을 clone()으로 복사하려고 하는 경우에는 원본과 복사본이 같은 객체를 공유하기 때문에 서로에게 영향을 주게 된다. 이를 얕은 복사라고 부르며, 원본이 참조하고 있는 객체까지 복사하는 것을 깊은 복사라고 부른다. 따라서 깊은 복사가 발생하면 원본과 복사본이 서로 영향을 끼치지 않는다.

getClass()

getClass() 메소드는 자신이 속한 클래스의 Class객체를 반환하는 메소드이다. Class객체는 클래스의 모든 정보를 담고 있고, 클래스 당 1개만 존재한다.

클래스 객체를 얻는 방법은 3가지가 존재한다.

Class cObj = new Card().getClass();
Class cObj = Card.class;
Class cObj = Class.forName("Card");

마지막 forName()은 특정 클래스파일을 메모리에 올릴 때 사용한다.

String클래스

String 클래스는 문자열을 저장하고 이를 다루는데 필요한 메소드를 제공한다. String 클래스의 가장 큰 특징이라고 한다면 변경이 불가능하다는 점이다. 한번 생성된 String인스턴스가 갖고 있는 문자열은 읽을수만 있고 변경이 불가능하다. 만약 참조변수에 새로운 값을 할당하면 새로운 인스턴스가 생성되고 참조변수는 새로운 인스턴스를 가리키게 된다.

String을 기본형 값으로, 기본형 값을 String으로 변환

// 기본형 값을 String으로 변환
int i = 100;
String str1 = i + "";
String str2 = String.valueOf(i);

/ String을 기본형 값으로 변환

int i = Integer.parseInt("100");
int i2 = Integer.valueOf("100");

StringBuffer클래스

StringBuffer클래스는 String클래스와 달리 인스턴스 생성때 지정한 문자열을 수정할 수 있고, 문자열 편집을 위한 buffer를 가지고 있다. buffer는 StringBuffer인스턴스 생성시에 저장될 문자열의 길이를 고려하여 충분히 여유있는 크기로 지정하는 것이 바람직하다.

StringBuffer 클래스는 equals메소드는 오버라이딩 되어있지 않아 등가비교연산자(==)과 같은 결과를 보이지만, toString()메소드는 오버라이딩 되어있어 호출시 담고있는 문자열을 반환한다.

StringBuilder클래스

StringBuffer는 멀티쓰레드에 안전하도록 동기화되어있다. 하지만 동기화가 StringBuffer의 성능을 떨어뜨리기에 멀티쓰레드로 작성된 프로그램이 아닌 경우, StringBuffer의 동기화는 성능을 떨어뜨리게 된다. 그렇기에 StringBuffer에서 동기화를 제외한 StringBuilder클래스를 새로 추가하게 되었다.

Reference

Java의 정석
남궁성의 정석코딩

profile
개발자 지망생입니다.

0개의 댓글