[Java] Object클래스, String클래스

킹발·2022년 9월 29일
0

Java

목록 보기
9/12
post-thumbnail

Object클래스

  • Object클래스는 java.lang 패키지에 들어 있다.
    • java.lang패키지는 자바프로그래밍에 가장 기본이 되는 클래스들을 포함한다.
    • java.lang패키지에 속한 클래스들은 import문 없이 사용할 수 있다.
  • 모든 클래스의 조상
  • Object클래스는 멤버변수는 없고 오직 11개의 메서드만 가지고 있다.

Object클래스의 메서드

Object클래스의 메서드설명
protected Object clone()객체 자신의 복사본을 반환한다.
public boolean equals(Object obj)객체 자신과 객체 obj가 같은 객체인지 알려준다.
protected void finalize()객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출된다. 이 때 수행되어야하는 코드가 있을 때 오버라이딩한다.
public Class getClass()객체 자신의 클래스 정보를 담고 있는 Class 인스턴스를 반환한다.
public int hashCode()객체 자신의 해시코드를 반환한다.
public String toString()객체 자신의 정보를 문자열로 반환한다.
public void notify()객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨운다.
public void notifyAll()객체 자신을 사용하려고 기다리는 쓰레드를 모두 깨운다.
public void wait(long timeout, int nanos)다른 쓰레드가 notify()나 notifyAll()을 호출할 때까지 현재 쓰레드를 무한히 또는 지정된 시간 동안 기다리게 한다.

equal()

두 객체의 같고 다름을 참조변수의 값으로 판단한다.

class Value {
    int value;

    public Value(int value) {
        this.value = value;
    }
}
public class ObjectEquals {
    public static void main(String[] args) {
        Value v1 = new Value(10);
        Value v2 = new Value(10);

        System.out.println( (v1.equals(v2)) ? "v1과 v2는 같습니다." : "v1과 v2는 다릅니다." );
    }
}
v1과 v2는 다릅니다.
  • 원래 의도는 같은 10이라는 value를 가지고 있으니 v1과 v2는 같습니다.가 출력되길 원했지만 v1과 v2는 다릅니다.가 출력되었다.
  • v1, v2 참조변수가 가지고 있는 주소값이 다르기 때문이다.
  • 객체를 생성할 때, 메모리의 비어있는 공간을 찾아 생성하므로 서로 다른 두 개의 객체가 같은 주소를 갖는 일은 있을 수 없다.

원래 의도대로 동작하게 하기 위해서 클래스에서 equals() 메서드는 오버라이드를 해준다.

class Value {
    int value;

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || this.getClass() != obj.getClass()) return false; //instanceof 역할

        Value value1 = (Value) obj;

        return value == value1.value;
    }
}
public class ObjectEquals {
    public static void main(String[] args) {
        Value v1 = new Value(10);
        Value v2 = new Value(10);

        System.out.println( (v1.equals(v2)) ? "v1과 v2는 같습니다." : "v1과 v2는 다릅니다." );
    }
}
v1과 v2는 같습니다.
  • 또 다른 예제 코드
import java.util.Objects;

class Value {
    int valueOne;
    int valueTwo;
    String message;

    public Value(int valueOne, int valueTwo, String message) {
        this.valueOne = valueOne;
        this.valueTwo = valueTwo;
        this.message = message;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Value value = (Value) o;

        if (valueOne != value.valueOne) return false;
        if (valueTwo != value.valueTwo) return false;
        return Objects.equals(message, value.message);
    }
}
public class ObjectEquals {
    public static void main(String[] args) {
        Value v1 = new Value(10, 20,"hi");
        Value v2 = new Value(10, 20,"hi");

        System.out.println( (v1.equals(v2)) ? "v1과 v2는 같습니다." : "v1과 v2는 다릅니다." );
    }
}
v1과 v2는 같습니다.
  • 필드에 정의되어 있는 변수들을 비교해서 모두 같다면 true를 반환하도록 equals()를 오버라이드 하는데, 필드에 static 변수가 있다면 어차피 모두 공통으로 관리되니까 굳이 비교할 필요 없다. 불필요한 코드가 된다.
  • String.equals() : 이미 오버라이드 되어 있다.

hashCode()

equals() 를 오버라이드 했다면, hashCode() 도 오버라이드 해야한다.

  • 왜냐하면, 인스턴스변수 값으로 객체의 같고 다름을 판단하도록 equals()를 오버라이드 했다, 그 결과 같은 객체라면 hashCode()를 호출했을 때의 결과값인 해시코드도 같아야 한다는 규칙이 존재

  • 참고 👉 equals와 hashCode는 왜 같이 재정의해야 할까?

import java.util.Objects;

class Value {
    int valueOne;
    int valueTwo;
    String message;

    public Value(int valueOne, int valueTwo, String message) {
        this.valueOne = valueOne;
        this.valueTwo = valueTwo;
        this.message = message;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Value value = (Value) o;
        return valueOne == value.valueOne && valueTwo == value.valueTwo 
        		&& Objects.equals(message, value.message);
    }

    @Override
    public int hashCode() {
        return Objects.hash(valueOne, valueTwo, message);
    }
}
public class ObjectEquals {
    public static void main(String[] args) {
        Value v1 = new Value(10, 20,"hi");
        Value v2 = new Value(10, 20,"hi");

        System.out.println( (v1.equals(v2)) ? "v1과 v2는 같습니다." : "v1과 v2는 다릅니다." );
    }
}

toString()

  • Object클래스에 정의된 toString()
    • 클래스 이름과 해시코드 정도를 확인할 수 있다.
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hasCode());
}
  • String클래스나 Date클래스는 가지고 있는 문자열이나, 날짜, 시간 정보를 문자열로 변환하여 반환하도록 오버라이딩 되어 있다.
  • 따라서 toString()은 일반적으로 변수들의 값을 문자열로 변환하여 반환하도록 오버라이딩되는 것이 보통이다.
class Student {
    private String name;
    private String gender;

    public Student(String name, String sex) {
        this.name = name;
        this.gender = sex;
    }

    @Override
    public String toString() {
        return "이름은 " + this.name + "이고 성별은 " + this.gender + "입니다.";
    }
}
public class ToStringEx {
    public static void main(String[] args) {

        Student s = new Student("홍길동", "남자");
        System.out.println(s);

    }
}

String클래스

Java에서는 문자열을 다루기 위한 String클래스를 제공한다.
String클래스를 사용해서 문자열을 저장하고 이를 다룰 수 있는 메서드를 사용한다.

  • String클래스는 문자열을 저장하기 위해서 문자형 배열 참조변수(char[]) value를 인스턴스 변수로 정의해놓고 있다.
public final class String implements java.io.Serializable, Comparable {
	private char[] value;
    	···

문자열의 비교

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

System.out.println(str1==str2);
System.out.println(str3==str4);
true
false
  • 문자열 리터럴은 이미 존재하는 것을 재사용하기 때문에 str1, str2상수 저장소에 올라가 있는 같은 abc 를 가르킨다.
  • String클래스의 생성자를 이용한 str3, str4 의 경우에는 new 연산자에 의해서 메모리할당이 이루어지기 때문에 항상 새로운 String인스턴스가 생성된다.

String클래스의 생성자와 메서드

length() - 문자열 길이 반환

String str = "Hello Java";
System.out.println(str.length()); 
// 출력결과 : 10

concat() - 문자열 결합

String str = "Hello ";
String lang = "Java";
System.out.println(str.concat(lang));
// 출력결과 : Hello Java

substring() - 문자열 자르기

String str = "Hello Java";
String lang = str.substring(6);

System.out.println(lang);
// 출력 결과 : Java

indexOf() - 문자가 위치한 인덱스 반환(앞부터 탐색)

String str = "Hello Java";
System.out.println(str.indexOf('a'));
// 출력 결과 : 7
// 문자가 존재하지 않는 경우엔 -1을 반환한다.

lastIndextOf() - 문자가 위치한 인덱스 반환(뒤부터 탐색)

String str = "Hello Java";
System.out.println(str.lastIndexOf('a'));
// 출력 결과 : 9

charAt() - 인덱스에 위치한 문자를 반환

String str = "Hello Java";
System.out.println(str.charAt(1));
// 출력 결과 : e

isEmpty() - 빈 문자열인지 확인

String str = "Hello Java";
System.out.println(str.isEmpty());
// 출력 결과 : false

replace() - 문자열 일부를 다른 문자열로 교체

String str = "Hello Java";
String newStr = str.replace("Java", "Python");

System.out.println(newStr);
// 출력 결과 : Hello Python

toUpperCase() / toLowerCase() - 대/소문자 통일

String str = "hello java";
String strUp = str.toUpperCase();

System.out.println(strUp);
// 출력 결과 : HELLO JAVA



String str = "HELLO JAVA";
String strLo = str.toLowerCase();

System.out.println(strLo);
// 출력 결과 : hello java

trim() - 문자열 앞/뒤 공백 제거

String str = "  Hellooo Java World   ";
String trimStr = str.trim();

System.out.println(trimStr);
// 출력 결과 : Hellooo Java World

split() - 문자열을 잘라서 배열로 반환

String str = "Hello Java";
String[] arr = str.split("");

System.out.println(Arrays.toString(arr));
// 출력 결과 : [H, e, l, l, o,  , J, a, v, a]

toCharArray() - split("")과 같은 기능

String str = "Hello Java";
char[] cArr = str.toCharArray();

System.out.println(cArr);
// 출력 결과 : Hello Java

getBytes() - byte 배열로 반환

String str = "Hello Java";
byte[] bytesArr = str.getBytes();

System.out.println(Arrays.toString(bytesArr));
// 출력 결과 : [72, 101, 108, 108, 111, 32, 74, 97, 118, 97]
// 반환된 숫자는 문자의 아스키코드 값

문자열 결합

join()

  • 여러 문자열 사이에 구분자를 넣어서 결합한다.
public class JoinEx {
    public static void main(String[] args) {
        String animals = "dog, cat, bear";
        String[] arr = animals.split(", ");
        String str = String.join(" & ", arr);
        System.out.println("str = " + str);
    }
}

StringJoiner

  • java.util.StringJoiner 클래스를 사용해서 문자열을 결합할 수도 있다.
import java.util.StringJoiner;

public class StringJoinerEx {
    public static void main(String[] args) {
        String animals = "dog, cat, bear";
        String[] arr = animals.split(", ");

        StringJoiner sj = new StringJoiner("/", "[", "]");

        for (String s : arr) {
            sj.add(s);
        }

        System.out.println(sj.toString());
    }
}

0개의 댓글