헬린코린이

[JAVA] .equals(), Object클래스, 형변환(캐스팅) 본문

Programming/Java

[JAVA] .equals(), Object클래스, 형변환(캐스팅)

HCD 2022. 11. 22. 22:24

먼저. equals()에 대해 알아보겠다

먼저 우리는 전에 이런 코드를 봤을 거다.

public class Test01 {
	public static void main(String[] args) {
		String a = "JAVA";
		String b = "JAVA";
		
		System.out.println(a==b);
	}
}

 

이 결과 true가 나올 것이다.

하지만

public class Test01 {
	public static void main(String[] args) {
		String a = new String("JAVA");
        	String b = new String("JAVA");
		
		System.out.println(a==b);
	}
}

이 코드는 false가 나올 것이다. 예상했을 텐데

== 비교 연산자는 주소 값을 비교하고

equals() 메서드는 내용 자체를 비교 즉, 데이터 값을 비교한다.

그렇다면 저 코드를 

public class Test01 {
	public static void main(String[] args) {
		String c = new String("JAVA");
        	String d = new String("JAVA");
		
		System.out.println(c.equals(d));
	}
}

이렇게 한다면 true가 나올 것이다

간단히 설명하면  String 클래스 a에 그냥 바로 "JAVA"로 초기화하면

String a, b는 "JAVA"의 주소 값을 가진다 그러니까 "JAVA"라는 공간이 생기고 그걸 String a, b가 참조한다.

String c,d는 == 비교 연산자로 비교하면 false가 나는 이유는 서로 각각 인스턴스를 생성하기 때문이다 쉽게 말하면

같은 내용을 각각 만든 것이다 예를 들면 하나는 우리 집 냉장고 하나는 옆집 냉장고 이렇게 만든 것을 비교하려고 하니

당연히 false가 나온다. 그래서 냉장고를 비교하지 말고 냉장고 안의 내용을 비교하면 냉장고 안에는 똑같은
"JAVA"가 들어있으니 true가 나오게 된다.

 

Object 클래스

Object 클래스는 모든 클래스의 조상이다. 앞에서 상속이란 걸 알아봤는데

예를 들어

class A{

}

이 코드가 있을 때

class A extends Object{

}

우리 눈에는 보이지 않지만 이 Object클래스를 상속받고 있다.

Object클래스에는 여러 가지 메서드가 정의되어 있지만

몇 가지만 이야기하겠다

우선 위에 이야기한 equals() 이 메서드도 Object클래스에 정의되어있다.

String 클래스 안에는 equals() 메서드가 정의되어있어 오버 라이딩을 안 해도 되지만

String클래스가 아닌 다른 클래스를 equals()로 비교하려면 오버 라이딩이 되어있어 한다.

예제를 보겠다.

public class Test03 {
	public static void main(String[] args) {
		Point p=new Point(10,20);
		ColorPoint cp1=new ColorPoint(1,2);
		ColorPoint cp2=new ColorPoint("파랑");
		ColorPoint cp3=new ColorPoint("파랑");
		p.move(); // (11,21)

		System.out.println(p);
		System.out.println(cp1);
		System.out.println(cp2);
		System.out.println(cp3);

		if(cp2.equals(cp3)) { 
			System.out.println("같다");
		}else {
			System.out.println("다르다");
		}

	}
}
class Point{
	int x;
	int y;
	Point(int x, int y){
		this.x=x;
		this.y=y;
	}
	void move() {
		this.x++;
		this.y++;
	}
	void move(int x, int y) {
		this.x+=x;
		this.y+=y;
	}
	@Override
	public String toString() { // 오버라이딩
		return "("+this.x+","+this.y+")";
	}
	@Override
	public boolean equals(Object obj) { 
		if(obj instanceof Point) {
			Point p=(Point)obj;
			if(p.x==this.x && p.y==this.y) {
				return true;
			}
		}
		return false;
	}
}
class ColorPoint extends Point{
	String color;
	ColorPoint(String color){
		this(color, 0, 0);
	}
	ColorPoint(String color, int x, int y){
		super(x, y);
		this.color=color;
	}
	ColorPoint(int x,int y){
		this("검정",x,y);
	}
	@Override
	public String toString() { // 오버라이딩
		return this.color+"("+this.x+","+this.y+")";
	}
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof ColorPoint) {
			ColorPoint cp=(ColorPoint)obj;
			if(cp.color == this.color) {
				if(cp.x==this.x) {
					if(cp.y==this.y) {
						return true;
					}
				}
			}
		}
		return false;
	}
}

이렇게 클래스 안에 오버 라이딩을 해줘야 한다.

 

다음으로 toString() 메서드를 보겠다.

toString을 오버 라이딩하지 않고 출력을 하면 주소 값을 출력될 것이다.

예제를 보겠다.

public class Test01 {
	public static void main(String[] args) {
		
		A aaa = new A (10,20);
		System.out.println(aaa);
		System.out.println(aaa.toString());
	}
}
class A{
	int a;
	int b;
	void func() {
		
	}
	A(int a, int b){
		this.a=a;
		this.b=b;
	}
	@Override
	public String toString() {
		return "a="+this.a+",b="+this.b;
	}

 

 

이렇게 하면 오버 라이딩을 한 toString() 메서드가 출력될 것이다.

 

마지막으로 형 변환에 대해 알아보겠다.

int a = 3.0;

위에 예제는 컴파일 에러가 뜰 것이다.

우리는 3.0을 원하는데 int타입은 정수만을 받는다.

왜 에러가 나는 걸까?

실제 데이터 3.0이라는 것이 a 변수에 들어가면 3으로 바뀌기 때문에 실제 데이터가 손실되는 것을 막고자 하는 것이다.

그래서 우리는

int a = (int)3.0;

이렇게 타입을 명시적으로 적어주어야 한다.

double a = 3;

그렇다면 이렇게 하면 어떻게 될까

3.0이 출력된다.

이건 에러가 나질 않는다. 이유는

int타입은 4byte고 double타입은 8byte이기 때문이다.

즉 낮은 byte에서 높은 byte로 형 변환하는 거는 문제가 없는데

높은 byte에서 낮은 byte타입으로 형 변환해줄 떼는 명시적으로 적어주어야 한다.

Comments