์๋ฐ Object ํด๋์ค ์ ๋ฆฌ - toString(), equals(), hashCode(), clone()
Object ํด๋์ค
- java.lang.Object
- ๋ชจ๋ ํด๋์ค์ ์ต์์ ํด๋์ค
Object ํด๋์ค๋ ์๋ฐ์์ ์ ๊ณตํ๋ ์ค์ํ ํด๋์ค ์ค ํ๋์ ๋๋ค.
java.lang.Object ํด๋์ค๋ ๋ชจ๋ ํด๋์ค์ ์ต์์ ํด๋์ค๋ก ๋ชจ๋ ํด๋์ค๋ Object ํด๋์ค๋ฅผ ์์๋ฐ์ต๋๋ค.
๋ฐ๋ผ์ ๋ชจ๋ ํด๋์ค๋ Object ํด๋์ค์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๊ณ ์ผ๋ถ ๋ฉ์๋๋ฅผ overrideํด์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
๋จ, ๋น์ฐํ final ๋ฉ์๋๋ overrideํ ์ ์์ต๋๋ค.
Object ํด๋์ค๊ฐ ๋ค์ด์๋ java.lang ํจํค์ง๋ ์ปดํ์ผ๋ฌ์ ์ํด ์๋์ผ๋ก import๋ฉ๋๋ค.
๊ทธ๋์ java.lang ํจํค์ง์ ์๋ ํด๋์ค๋ ๋ฐ๋ก importํ์ง ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฃผ๋ก clone(), equals(), hashCode(), toString()์ ํํ overrideํด์ ์ฌ์ฉํฉ๋๋ค.
๊ฐ ๋ฉ์๋์ ๋ํด ์์๋ด ์๋ค.
1. toString()
- ๊ธฐ๋ณธ ๋์: ๊ฐ์ฒด์ ํด์์ฝ๋ ์ถ๋ ฅ
- override ๋ชฉ์ : ๊ฐ์ฒด์ ์ ๋ณด๋ฅผ ๋ฌธ์์ด ํํ๋ก ํํํ๊ณ ์ ํ ๋
package com.yoon._object;
public class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public static void main(String[] args) {
Book book = new Book("๊น์ ๋ฐค ๋ถ์์์", "๋ชจ๋ฆฌ์ค ์๋ฅ");
System.out.println(book);
}
}
๐ฅ ์คํ ๊ฒฐ๊ณผ
com.yoon._object.Book@35bbe5e8
Process finished with exit code 0
์ด๋ ๊ฒ toString()์ overrideํ์ง ์๊ณ ์ธ์คํด์ค๋ฅผ ์ถ๋ ฅํ๋ฉด 'ํด๋์คํ๋ค์@ํด์์ฝ๋'๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค. ์ด๊ฒ์ด toString()์ ์ํ์ ๋๋ค.
toString()์ ์ํ
getClass().getName() + '@' + Integer.toHexString(hashCode())
๋ค๋ฅธ ์์ ๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
String str = new String("Apple");
System.out.println(str);
๐ฅ ์คํ ๊ฒฐ๊ณผ
Apple
Process finished with exit code 0
String ๊ฐ์ฒด๋ฅผ ์ถ๋ ฅํ๋ฉด String ๊ฐ์ฒด๊ฐ ์ ์ฅํ๊ณ ์๋ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋ฉ๋๋ค.
์ด ์ด์ ๋ jdk์ String ํด๋์ค๋ toString()์ overrideํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
System.out.println(str)์ System.out.println(str.toString())๊ณผ ๊ฐ์ต๋๋ค.
์ฆ toString()์ ์ด๋ค ๊ฐ์ฒด์ ์ ๋ณด๋ฅผ ๋ฌธ์์ด ํํ๋ก ํํํด์ผ ํ ๋ ํธ์ถํ๋ ๋ฉ์๋์ ๋๋ค.
๋ค์ Book ์์ ์์ toString()์ overrideํด์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ด ์๋ค.
package com.yoon._object;
public class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
'}';
}
public static void main(String[] args) {
Book book = new Book("๊น์ ๋ฐค ๋ถ์์์", "๋ชจ๋ฆฌ์ค ์๋ฅ");
System.out.println(book);
}
}
๐ฅ ์คํ ๊ฒฐ๊ณผ
Book{title='๊น์ ๋ฐค ๋ถ์์์', author='๋ชจ๋ฆฌ์ค ์๋ฅ'}
Process finished with exit code 0
2. equals()
- ๊ธฐ๋ณธ ๋์: '==' ์ฐ์ฐ ๊ฒฐ๊ณผ ๋ฐํ
- override ๋ชฉ์ : ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ์ ์์นํ๋ ๊ฐ์ฒด์ฌ๋ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋์ผํจ์ ๊ตฌํํ๊ธฐ ์ํด
equals()๋ฅผ ์ฌ์ฉํด ๋ ๊ฐ์ฒด์ ๋์ผํจ์ ๋ ผ๋ฆฌ์ ์ผ๋ก override ํ ์ ์์ต๋๋ค.
'๋ฌผ๋ฆฌ์ ๋์ผํจ'์ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ๊ฐ์ ์ฃผ์๋ฅผ ๊ฐ๋ ๊ฒ์, '๋ ผ๋ฆฌ์ ๋์ผํจ'์ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋ค๋ฅธ ์์น์ ์์ง๋ง ๊ฐ์ id์ ํ์ ๊ฐ์ฒด, ๊ฐ์ id์ ์ฃผ๋ฌธ ๊ฐ์ฒด์ ๊ฐ์ด ๋๋ฉ์ธ์ ๊ตฌ๋ถํ ์ ์๋ ๊ณ ์ ํ ๊ฐ ๋ฑ์ ์ํด ๋์ผํ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
public class User {
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public static void main(String[] args) {
User user1 = new User(1001, "ํ๊ธธ๋");
User user2 = new User(1001, "ํ๊ธธ๋");
System.out.println(user1.equals(user2));
}
}
๐ฅ ์คํ ๊ฒฐ๊ณผ
false
Process finished with exit code 0
equals()์ ๊ธฐ๋ณธ ๋์์ '==' ์ฐ์ฐ์ด๊ธฐ ๋๋ฌธ์ ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฐธ์กฐ๋ณ์๋ฅผ equals()๋ก ๋น๊ตํ๋ฉด false๊ฐ ๋ฆฌํด๋ฉ๋๋ค.
์ด๋ฐ ๊ฒฝ์ฐ equals()๋ฅผ overrideํ์ฌ ๋ ผ๋ฆฌ์ ์ธ ๋์ผ์ฑ์ ๊ฐ๋๋ก ํ ์ ์์ต๋๋ค.
๋ค์์ ์ ์์ ์์ User ํด๋์ค์์ equals()๋ฅผ override ํ ๊ฒ์ ๋๋ค.
public class User {
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
return this.getId() == ((User)obj).getId();
} else {
return false;
}
}
public static void main(String[] args) {
User user1 = new User(1001, "ํ๊ธธ๋");
User user2 = new User(1001, "ํ๊ธธ๋");
System.out.println(user1.equals(user2));
}
}
๐ฅ ์คํ ๊ฒฐ๊ณผ
true
Process finished with exit code 0
equals()์ ๋ฐํ๊ฐ์ด true๋ก ๋ ๊ฐ์ฒด๊ฐ ๊ฐ๋ค๋ ์๋ฏธ๋ ๊ฐ์ ํด์์ฝ๋๊ฐ์ ๊ฐ๋๋ค๋ ๊ฒ์ ๋๋ค.
hashCode()
- ๊ธฐ๋ณธ ๋์: JVM์ด ๋ถ์ฌํ ์ฝ๋๊ฐ. ์ธ์คํด์ค๊ฐ ์ ์ฅ๋ ๊ฐ์๋จธ์ ์ ์ฃผ์๋ฅผ 10์ง์๋ก ๋ฐํ
- override ๋ชฉ์ : ๋ ๊ฐ์ ์๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ์ ์์นํ ๊ฐ์ฒด๊ฐ ๋์ผ์ฑ์ ๊ฐ๊ธฐ ์ํด
ํด์์ฝ๋๋ JVM์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋ณํํด์ ๋ถ์ฌํ๋ ์ฝ๋์ ๋๋ค.
์ค์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ๊ณผ๋ ๋ณ๊ฐ์ ๊ฐ์ด๋ฉฐ ์ค์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ System ํด๋์ค์ identityHashCode()๋ก ํ์ธํ ์ ์์ต๋๋ค.
์๋ฐ์์์ ๋์ผ์ฑ์ equals()์ ๋ฐํ๊ฐ์ด true, hashCode() ๋ฐํ๊ฐ์ด ๋์ผํจ์ ์๋ฏธํฉ๋๋ค.
๊ทธ๋์ ์ผ๋ฐ์ ์ผ๋ก equals()์ hashCode()๋ ํจ๊ป override ํฉ๋๋ค.
public class User {
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
return this.getId() == ((User)obj).getId();
} else {
return false;
}
}
public static void main(String[] args) {
User user1 = new User(1001, "ํ๊ธธ๋");
User user2 = new User(1001, "ํ๊ธธ๋");
System.out.println("user1.equals(user2): " + user1.equals(user2));
System.out.println("user1.hashCode(): " + user1.hashCode());
System.out.println("user2.hashCode(): " + user2.hashCode());
}
}
๐ฅ ์คํ ๊ฒฐ๊ณผ
user1.equals(user2): true
user1.hashCode(): 901506536
user2.hashCode(): 747464370
Process finished with exit code 0
์ง๊ธ์ User ๊ฐ์ฒด user1๊ณผ user2๊ฐ ์๋ก ๋ค๋ฅธ ํด์์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.
์๋ฐ์์์ ๋์ผ์ฑ์ ๊ตฌํํ๊ธฐ ์ํด์๋ hashCode()๋ override ํด์ผํ๋ฉฐ, equals()๋ฅผ overrideํ ๋ ์ฌ์ฉํ ๋ฉค๋ฒ๋ฅผ ํ์ฉํ๋ฉด ๋ฉ๋๋ค.
์ฌ๊ธฐ์๋ id๊ฐ ๋๊ฒ ์ง์.
public class User {
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
return this.getId() == ((User)obj).getId();
} else {
return false;
}
}
@Override
public int hashCode() {
return getId();
}
public static void main(String[] args) {
User user1 = new User(1001, "ํ๊ธธ๋");
User user2 = new User(1001, "ํ๊ธธ๋");
System.out.println("user1.equals(user2): " + user1.equals(user2));
System.out.println("user1.hashCode(): " + user1.hashCode());
System.out.println("user2.hashCode(): " + user2.hashCode());
System.out.println("System.identityHashCode(user1): " + System.identityHashCode(user1));
System.out.println("System.identityHashCode(user2): " + System.identityHashCode(user2));
}
}
๐ฅ ์คํ ๊ฒฐ๊ณผ
user1.equals(user2): true
user1.hashCode(): 1001
user2.hashCode(): 1001
System.identityHashCode(user1): 901506536
System.identityHashCode(user2): 747464370
Process finished with exit code 0
์๋ฐ์ Integer ํด๋์ค๋ Object ํด๋์ค์ hashCode()๋ฅผ overrideํ๊ณ ์์ต๋๋ค.
Integer i1 = 100;
Integer i2 = 100;
System.out.println("i1.hashCode(): " + i1.hashCode());
System.out.println("i2.hashCode(): " + i2.hashCode());
๐ฅ ์คํ ๊ฒฐ๊ณผ
i1.hashCode(): 100
i2.hashCode(): 100
Process finished with exit code 0
clone()
- ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ ๋ง๋ฆ
- Prototype์ผ๋ก๋ถํฐ ๊ฐ์ ์์ฑ๊ฐ์ ๊ฐ์ง ๋ณต์ฌ๋ณธ์ ์์ฑ
- ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ ๋ณด์๋์ ์๋ฐฐ๋ ๊ฐ๋ฅ์ฑ์ด ์์ผ๋ฏ๋ก ๋ณต์ ํ ๊ฐ์ฒด๋ Cloneable ์ธํฐํ์ด์ค๋ฅผ ๋ช ์ํด์ผ ํจ
clone() ๋ฉ์๋๋ ๊ฐ์ฒด๋ฅผ ๋ณต์ ํ ๋ ์ฌ์ฉํ๋ฉฐ private ํ๋๋ ๋ณต์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ๋ณด์๋์ ์๋ฐฐ๋ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ Cloneable ์ธํฐํ์ด์ค๊ฐ ๋ช ์๋ผ์๋ ํด๋์ค๋ง clone()์ ํตํด ๊ฐ์ฒด๋ฅผ ๋ณต์ ํ ์ ์์ต๋๋ค.
์์์ ์ฌ์ฉํ Book ํด๋์ค์์ clone()์ overrideํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ณต์ ํด๋ณด๊ฒ ์ต๋๋ค.
public class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Book book1 = new Book("๊น์ ๋ฐค ๋ถ์์์", "๋ชจ๋ฆฌ์ค ์๋ฅ");
System.out.println(book1);
Book book2 = (Book) book1.clone();
System.out.println(book2);
}
}
clone()์ super.clone()์ ๊ทธ๋๋ก ํธ์ถํ๋ฉด ๋ฉ๋๋ค.
๐ฅ ์คํ ๊ฒฐ๊ณผ
Book{title='๊น์ ๋ฐค ๋ถ์์์', author='๋ชจ๋ฆฌ์ค ์๋ฅ'}
Exception in thread "main" java.lang.CloneNotSupportedException: com.yoon._object.Book
at java.base/java.lang.Object.clone(Native Method)
at com.yoon._object.Book.clone(Book.java:23)
at com.yoon._object.Book.main(Book.java:31)
Process finished with exit code 1
CloneNotSupportedException์ด ๋ฐ์ํฉ๋๋ค.
์ด์ ๋ Book ํด๋์ค์ Cloneable ์ธํฐํ์ด์ค๊ฐ ๋ช ์๋ผ์์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํฉ๋๋ค.
public class Book implements Cloneable
๐ฅ ์คํ ๊ฒฐ๊ณผ
Book{title='๊น์ ๋ฐค ๋ถ์์์', author='๋ชจ๋ฆฌ์ค ์๋ฅ'}
Book{title='๊น์ ๋ฐค ๋ถ์์์', author='๋ชจ๋ฆฌ์ค ์๋ฅ'}
Process finished with exit code 0
Cloneable ์ธํฐํ์ด์ค๋ ๋น ์ธํฐํ์ด์ค์ ๋๋ค.
public interface Cloneable {
}
๋ฐ๋ผ์ Cloneable ์ธํฐํ์ด์ค๋ฅผ implementsํด๋ ๊ตฌํํด์ผ ํ ๋ฉ์๋๋ ์์ต๋๋ค.
์ด๋ฐ ์ธํฐํ์ด์ค๋ฅผ '๋งํฌ ์ธํฐํ์ด์ค'๋ผ๊ณ ๋ ํฉ๋๋ค.
์ ๋ฆฌํ๋ฉด clone()์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋ณต์ ํ๊ธฐ ์ํด์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋ค์ด ํ์ํฉ๋๋ค.
- Cloneable ์ธํฐํ์ด์ค ๋ช ์ ํ์
- ๋ณต์ ๋ ๊ฐ์ฒด๋ Object๋ก ๋ฐํ๋๋ฏ๋ก ๋ช ์์ ์ธ ์บ์คํ ํ์
- ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ณต์ ๋๋ฉด์ CloneNotSupportedException์ด ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ์์ธ์ฒ๋ฆฌ ํ์
์ฐธ๊ณ - finalize()
Object ํด๋์ค์ finalize() ๋ฉ์๋๋ ์ง์ ํธ์ถํ๋ ๋ฉ์๋๊ฐ ์๋๋ผ ๊ฐ์ฒด๊ฐ ํ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋ ๋ ๊ฐ๋น์ง์ฝ๋ ํฐ๊ฐ ํธ์ถํ๋ ๋ฉ์๋์ ๋๋ค.
์ด ๋ฉ์๋๊ฐ override๋ผ์์ผ๋ฉด ๊ฐ๋น์ง์ฝ๋ ํฐ๊ฐ ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์คํํฉ๋๋ค.
์ฆ finalize()์๋ ๊ฐ์ฒด๊ฐ ํด์ ๋ ๋ ๋ฆฌ์์ค ํด์ , ์์ผ close ๋ฑ์ ํ์ํ ๊ฒ๋ค์ ๊ตฌํํด์ฃผ๋ฉด ๋ฉ๋๋ค.
'Javaยท๏ปฟServletยท๏ปฟJSP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JAVA ์ ๋ค๋ฆญ(Generics) ํด๋์ค์ ๋ฉ์๋ (1) | 2020.07.11 |
---|---|
JAVA์ ๊ฐ์ฒด ์ง๋ ฌํ(Serialization)์ JSON ์ง๋ ฌํ (0) | 2020.07.10 |
[JAVA ๋์์ธ ํจํด] ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด (59) | 2020.06.26 |
[JAVA ๋์์ธ ํจํด] static์ ์์ฉํ ์ฑ๊ธํค ํจํด(Singleton Pattern) ๊ตฌํ (0) | 2020.06.18 |
JAVA ์ฌ๊ท ํธ์ถ(Recursive Call) ์์ (2) | 2020.04.07 |
๋๊ธ