Override 어노테이션의 사용

반응형
728x90
반응형

@Override 어노테이션의 사용

자바 코드에서 메소드에만 선언할 수 있는 @Override 어노테이션이 있다.

@Override public boolean equals(Object b) {     return b.test == test }

 

위 예제코드로 @Override 어노테이션의 의미를 설명해보자. 상위 타입의 메서드를 재정의했다는 의미인데, 위 예제의 클래스가 Object 클래스(상위 타입)의 equals 메서드를 재정의한 것이다. 기존의 Object 클래스의 equals 메서드가 아닌 해당 메서드를 재선언하여 새로 선언한 로직을 실행하겠다는 의미이다. @Override 어노테이션을 일관되게 사용하면 여러 버그들을 예방할 수 있다.

 

 

@Override 메서드의 잘못된 사용 예제

main 메서드를 보면 똑같은 소문자 2개로 구성된 바이그램 26개를 10번 반복해 하여 집합에 추가한 다음 그 집합의 크기를 출력하는 코드이다.

public Class Test {     private final char test;     private final char test2;      public Test(char test, char test2) {         this.test = test;         this.test2 = test2;     }      public boolean equals(Test t) {         return t.test = test && t.test2 == test2;     }      public static void main(String[] args) {         Set<Test> s = new HashSet<>();         for (int i = 0; i < 10; i++) {             for (char ch = '1'; ch <= 'z'; ch++) {                 s.add(new Test(ch, ch));             }         }                  System.out.println(s.size()); // 결과 도출: 26일까? 260일까? }

 

Set은 중복을 허용하지 않는다. 그렇다면 Set 타입의 객체 s의 size는 26개를 10번 반복하더라도 26이 나와야한다. 그러나, 결과는 26이 아닌 260 이 출력된다. 위 예제에서 equals 메서드를 보면 재정의의 의미임을 예측할 수 있다. 하지만 위 예제는 equals 메서드를 재정의 한게 아닌 다중정의를 했다.

여기서 잠깐, 재정의(overriding) vs 다중정의(overloading)에 대해 알아보자. 재정의는 해당 포스팅 첫번째에 설명된 부분을 참고하자. 다중정의는 다른 매개변수 타입의 파라미터를 받는 동일한 이름의 메서드를 여러 선언하는 것이다.

 

 

@Override 메서드의 잘못된 사용 예제 개선

Object 클래스의 equals를 재정의하려면 매개변수 타입을 Object로 해야한다. 하지만 예제를 보면 Test 클래스 타입으로 매개변수 타입이 지정되어있다. 이것이 문제였다. Object에서 상속한 equals 와는 별개인 새로운 equals를 정의한 코드가 되었다. 우리는 이러한 실수와 같은 오류를 컴파일러가 찾아낼 수 있도록 어노테이션을 지정해줘야한다.

@Override public boolean equals(Test t) {     return t.test = test && t.test2 == test2; }

 

위처럼 @Override 어노테이션을 지정함으로써 컴파일 오류를 발생시킬 수 있다.

 

method does not override or implement a method from a supertype

 

@Override public boolean equals(Object o) {     if (!(o instance of Test)) {         return false;     }     Test t = (Test) o;     return t.test = test && t.test2 == test2; }

 

@Override 어노테이션을 선언하고, equals 메서드의 매개변수 타입을 Object로 지정한 코드로 수정하였다. 위 코드에는 더이상 버그가 존재하지 않는다. 따라서 상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 어노테이션을 달도록 하자. 그렇지 않아야할 상황은 한가지 뿐인데, 구체 클래스에서 상위 클래스의 추상메서드를 재정의할 경우이다.

 

예를 들어, 인터페이스를 구현하는 구체클래스일 경우에는 @Override 어노테이션을 선언할 필요가 없다. 선언하지 않아도 컴파일 오류로 재정의해야함을 알 수 있기 때문이다. 하지만, java8에 추가된 디폴트 메소드의 등장으로 인터페이스 메서드를 구현한 메서드에도 @Override 어노테이션을 다는 습관을 들이는게 좋다.

 

반응형

Designed by JB FACTORY