toString()
Object.toString() 메서드는 객체의 정보를 문자열 형태로 제공한다. 디버깅과 로깅에 유용하게 사용된다.
public class ToStringMain1 {
public static void main(String[] args) {
Object object = new Object();
String string = object.toString();
System.out.println(string);
System.out.println(object);
}
}
Object가 제공하는 toString() 메서드는 기본적으로 패키지를 포함한 객체의 이름과 참조값(해시코드)를 16진수로 제공한다.
toString()의 결과를 출력한 코드와 object를 출력한 코드의 결과가 완전히 같다.
그 이유는 System.out.println() 메서드는 내부에서 toString()을 호출한다.
toString() 오버라이딩
Object.toString() 메서드가 클래스 정보와 참조값을 제공하지만 객체의 상태를 적절히 나타내지 못하기 때문에 보통 toString()을 재정의해서 보다 유용한 정보를 제공하는 것이 일반적이다.
package lang.object.toString;
public class Dog {
private String dogName;
private int age;
public Dog(String dogName, int age) {
this.dogName = dogName;
this.age = age;
}
@Override
public String toString(){
return "Dog{" +
"dogName='" + dogName + '\'' +
", age=" + age +
'}';
}
}
package lang.object.toString;
public class ObjectPrinter {
public static void print(Object obj){
String string = "객체 정보 출력:" + obj.toString();
System.out.println(string);
}
}
package lang.object.toString;
public class ToStringMain2 {
public static void main(String[] args) {
Car car = new Car("Model ");
Dog dog1 = new Dog("멍멍이1",2);
Dog dog2 = new Dog("멍멍이2",5);
System.out.println(car.toString());
System.out.println(dog1.toString());
System.out.println(dog2.toString());
System.out.println(car);
System.out.println(dog1);
System.out.println(dog2);
ObjectPrinter.print(car);
ObjectPrinter.print(dog1);
ObjectPrinter.print(dog2);
}
}
Car 인스턴스는 toString() 을 재정의 하지 않았기 떄문에 Object가 제공하는 기본 toString() 메서드를 사용한다.
Dog 인스턴스는 toString() 을 재정의 한 덕분에 객체의 상태를 명확하게 확인할 수 있다.
Object와 OCP
다형적 참조 : print(Object obj), Object 타입을 매개변수로 사용해서 다형적 참조를 사용한다.
Car, Dog 인스턴스를 포함한 세상 모든 객체 인스턴스를 인수로 받을 수 있다.
메서드 오버라이딩: Object는 모든 클래스의 부모이다. Dog, Car와 같은 구체적인 클래스는 Object가 가지고 있는 toString() 메서드를 오버라이딩 할 수 있다. print(Object obj) 메서드는 Dog, Car와 같은 구체적인 타입에 의존하지 않고 추상적인 Object 타입에 의존하면서 런타임에 각 인스턴스의 toString()을 호출할 수 있다.
OCP원칙
- Open : 새로운 클래스를 추가하고, toString() 을 오버라이딩해서 기능을 확장할 수 있다.
- Closed : 새로운 클래스를 추가해도 Object 와 toString()을 사용하는 클라이언트 코드인 ObjectPrinter는 변경하지 않아도 된다.
System.out.println()
System.out.println() 메서드도 Object 매개변수를 사용하고 내부에서 toString()을 호출한다.
System.out.println() 를 사용하면 세상의 모든 객체의 정보를 편리하게 출력할 수 있다.
equals() - 1. 동일성과 동등성
자바는 두 객체가 같다라는 표현을 2가지로 분리해서 제공한다.
- 동일성 : == 연산자를 사용해서 두 객체의 참조가 동일한 객체를 가리키고 있는지 확인
- 동등성 : equals() 메서드를 사용하여 두 객체가 논리적으로 동등한지 확인
package lang.object.equals;
public class UserV1 {
private String id;
public UserV1(String id) {
this.id = id;
}
}
package lang.object.equals;
public class EqualsMainV1 {
public static void main(String[] args) {
UserV1 user1 = new UserV1("id-100");
UserV1 user2 = new UserV1("id-100");
System.out.println("identity = " + (user1 == user2));
System.out.println("equality = " + (user1.equals(user2)));
}
}
Object가 기본으로 제공하는 equals()는 == 동일성 비교를 제공한다.
클래스마다 동등성을 처리하는 기준이 다르기 때문에 equals() 메서드를 재정의 해야한다.
package lang.object.equals;
import java.util.Objects;
public class UserV2 {
private String id;
public UserV2(String id) {
this.id = id;
}
// @Override
// public boolean equals(Object obj) {
// UserV2 user = (UserV2) obj;
// return id.equals(user.id);
// }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserV2 userV2 = (UserV2) o;
return Objects.equals(id, userV2.id);
}
}
UserV2는 id가 같으면 논리적으로 같은 객체로 정의한다.
package lang.object.equals;
public class EqualsMainV2 {
public static void main(String[] args) {
UserV2 user1 = new UserV2("id-100");
UserV2 user2 = new UserV2("id-100");
System.out.println("identity = " + (user1 == user2));
System.out.println("identity = " + (user1.equals(user2)));
}
}
동일성 : 객체의 참조가 다르므로 동일성은 다르다.
동등성 : user1 , user2는 서로 다른 객체이지만 둘다 같은 id를 가지고 있어 동등하다.
equals() 메서드를 구현할 때 지켜야 하는 규칙
- 반사성 : 객체는 자기 자신과 동등해야한다.
- 대칭성 : 두 객체가 서로에 대해 동일하다고 판단되면, 이는 양방향으로 동일해야 한다.
- 추이성 : 만약 한 객체가 두번쨰 객체와 동일하고, 두번째 객체가 세번째 객체와 동일하다면 가능
- 일관성 : 두 객체의 상태가 변경되지 않는 한 equals() 메서드는 항상 동일한 값 반환
- null에 대한 비교 : 모든 객체가 null과 비교했을때 false를 반환해야한다.
Reference
Object 배열 | 김영한의 실전 자바 - 중급 1편
Object 배열
www.inflearn.com
'JAVA' 카테고리의 다른 글
Lv1 삼총사 (0) | 2025.07.14 |
---|---|
김영한의 실전 자바 중급 1편 (3) (0) | 2025.07.13 |
김영한의 실전 자바 중급 1편 (1) (0) | 2025.07.06 |
문자열 뒤집기 - StringBuilder.reverse() (0) | 2025.06.12 |
김영한의 실전 자바 기본편 - 8일차 (0) | 2025.05.10 |