java.lang패키지
equals
예제
public static void main(String[] args) {
Value v1 = new Value(10);
Value v2 = new Value(20);
System.out.println("test");
if (v1.equals(v2)) {
System.out.println("같음");
}
else {
System.out.println("다름");
}
v2 = v1;
if (v1.equals(v2)) {
System.out.println("두번째 같음");
}
else {
System.out.println("두번째 다름");
}
}
equals메서드는 객체의 주소의 일치여부를 보는 메서드이다.
따라서 첫번째는 객체의 주소가 다름으로 "다름"이 출력되고
두번째는 v2 = v1을 통해 같은 객체의 주소를 가르키고있음으로 "두번째 같음"이 출력된다.
예제2
Person p1 = new Person(8011);
Person p2 = new Person(8011);
if (p1==p2) {
System.out.println("같음");
}
else {
System.out.println("다름");
}
if (p1.equals(p2)) {
System.out.println("두번째 같음");
}
}
}
class Person {
long id;
public boolean equals(Object obj) {
if (obj instanceof Person) {
return id == ((Person)obj).id;
}
else {
return false;
}
}
Person(long id) {
this.id =id;
}
}
두번째 예제는 객체의 주소값이 아닌 객체의 값을 비교하기위해 equals를 오버라이딩 한것이다.
return id == ((person)obj).id ; 는 obj가 조상클래스이기 때문에 id를 참조하기 위해서는 Person타입으로 형변환이 필요해서 하였다.
출력결과는 다름 , 두번째 같음 이 출력된다.
hashCode()
해시함수는 찾고자하는 값을 입력하면 그 값이 저장된 위치를 알려주는 해시코드를 반환한다.
같은 객체라면 hashCode를 호출하였을 때 결과값인 해시코드고 같아야한다.
예제
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));
}
String 클래스는 문자열의 내용이 같으면 동일한 해시코드를 반환하도록 hashCode메서드에 오버라이딩 되어있어서
true , str1, str2 모두 동일한 해시코드가 반환된다.
반면 System.identity는 객체의 주소값으로 해시코드를 생성해 항상 다른 해시코드값을 반환한다.
따라서 str1 과 str2는 해시코드는 같지만 다른 객체이다.
toString()
인스턴스에 대한 정보를 문자열로 제공해주는 메서드이다.
public static void main(String[] args) {
int[] arr = {1,2,3};
int num = 1;
System.out.println(arr.toString());
출력 : [I@2d98a335
toString() 메서드는 오버라이딩이 가능하다.
Card c1 = new Card();
System.out.println(c1.toString());
}
}
class Card {
int number =2;
public String toString() {
return "number = " + number;
}
}
출력 : number = 2
clone()
clone은 자신을 복제하여 새로운 인스턴스를 생성한다.
Object클래스에 clonew은 인스턴스변수의 값만 복사하여 참조타입의 인스턴스 변수는 완전히 복제가 이루어지지않는다.
이렇기 때문에 clone 메서드를 오버라이딩 할 필요가 있다.
방법
example p1 = new example(3,5);
example p2 = (example)p1.clone(); //Object클래스와 example클래스이기 때문에 형변환 필요
}
}
class example implements Cloneable { //clonealbe이 있어야지만 clone을 쓸수있다. 없으면 예외가 발생
int x ,y
example(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return x + " " + y;
}
protected Object clone() { //protected말고 public 을 쓰면 상속관계가 아니여도 사용가능하다.
Object obj = null;
try {
obj = super.clone(); //Object에 있는 클론 클론은 예외처리 필수
} catch (CloneNotSupportedException e) {}
return obj;
}
}
공변반환타입: 조상메서드의 반환타입을 자손 클래스
public example clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e){}
return (example)obj;
}
의 타입으로 변경가능한것 - 반환을 클래스 타입으로 반환한다.
clone의 문제
복제에는 얕은 복사와 깊은 복사가 존재한다.
얕은복사 = 객체가 참조하는 객체까지는 참조하지않는다. 원본과 복제본이 같은 객체 공유
깊은 복사 = 원본과 복제본이 다른 객체를 참조. good
앝은복사
example코드는 위에
int [] arr = {1,2,3};
arrTest t1 = new arrTest(arr,new example(7,8));
arrTest t2 = t1.shallowCopy();
t2.e.x=10;
t2.x[1] = 10;
System.out.println(t1);
System.out.println(t2);
}
}
class arrTest implements Cloneable{
int[] x;
example e;
arrTest(int[] x,example e) {
this.x = x;
this.e = e;
}
public String toString() {
return Arrays.toString(x) + e;
}
public arrTest shallowCopy() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e){}
return (arrTest) obj;
}
}
얕은 복사로인해 복사본을 변경했음에도 불구하고 원본까지 변경이됨.(같은 인스턴스를 가르키고있기때문에)
깊은복사
int [] arr = {1,2,3};
arrTest t1 = new arrTest(arr,new example(7,8));
arrTest t2 = t1.shallowCopy();
arrTest t3 = t1.deepCopy();
t2.e.x=10;
t2.x[1] = 10;
System.out.println(t1);
System.out.println(t2);
System.out.println(t3);
}
}
class arrTest implements Cloneable{
int[] x;
example e;
arrTest(int[] x,example e) {
this.x = x;
this.e = e;
}
public String toString() {
return Arrays.toString(x) + e;
}
public arrTest shallowCopy() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e){}
return (arrTest) obj;
}
public arrTest deepCopy() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e){}
arrTest at = (arrTest) obj; //새롭게 인스턴스를 하나 생성
at.e = new example(this.e.x,this.e.y); //생성한 객체의 값을 지정
return at;
}
}
깊은 복사로 복사한 example 객체의 값은 변경해도 바뀌지않는다. -> copy는 원본 객체가 가지고 있는 값만 그대로 복사
deepcopy = 원본이 참조하고 있는 객체까지 복사!!!!
'IT 관련 > JAVA' 카테고리의 다른 글
자바(java) 날짜(Date,Calendar,time) (0) | 2022.08.03 |
---|---|
자바 java.lang 패키지(2) (0) | 2022.07.26 |
자바 예외처리 (0) | 2022.07.07 |
자바 객체지향II (추상화, 인터페이스) (0) | 2022.06.30 |
자바 객체지향언어II(제어자 ,다형성) (0) | 2022.06.29 |