2010-01-02 2 views
3

인터페이스를 구현할 때 "콘크리트 메서드 ..."컴파일 타임 오류를 무시할 수 있습니까?인터페이스를 구현할 때 "구체적인 방법을 재정의하지 마십시오 ..."컴파일 시간 오류가 발생할 수 있습니까?

더 명확한 예 :

인터페이스가 포함 된 프레임 워크를 빌드합니다. 프레임 워크를 사용하려면 개발자가 일부 인터페이스를 구현해야합니다. 그러나 equals(Object object)hashCode()Object 메소드를 덮어 쓰지 않으면 내부 API 로직이 손상됩니다!

모든 것은이 javadoc의에서 언급하지만 난 컴파일 타임 오류 또는 인터페이스가 일부 콘크리트 방법를 오버라이드 (override)하지 않고 구현 어쩌면 런타임 예외을 갖고 싶어.

답변

7

Java는 Java 6부터 시작하여 주석 처리 기능을 제공합니다 (예 : Source Code Analysis).(기술적으로는 Java 5의 일부이지만 Java 6에서는 특수 도구가 아닌 컴파일러 단계에 통합했습니다.) Sun에서 제공하는 Getting Started guide.

주석 프로세서는 프로젝트를 빌드하는 동안 컴파일러에 의해 호출되고 컴파일러에서와 마찬가지로 오류가 발생할 수 있습니다. Java가 규정 한 것보다 더 많은 규칙을 시행하는 깔끔한 방법입니다. 또는 META-INF/services 파일을 추가 (컴파일러 옵션에 -processor com.notnoop.CheckMethodOverride을 추가하여) 주석 프로세서가 컴파일러 옵션에 직접 지정할 수 있습니다

@SupportedSourceVersion(SourceVersion.RELEASE_6) 
@SupportedAnnotationTypes("*") 
public class CheckMethodOverride extends AbstractProcessor { 
    // returns true if the class has a method with the specified method name 
    // and specified number of parameters 
    private static boolean hasMethod(TypeElement clazz, String methodName, int arity) { 
     for (ExecutableElement method : 
       ElementFilter.methodsIn(clazz.getEnclosedElements())) { 
      if (method.getSimpleName().equals(methodName) 
        && method.getParameters().size() == arity) 
       return true; 
     } 
     return false; 
    } 

    // the interface whose subclasses must override hashCode and equals 
    TypeMirror interfaceToCheck; 

    @Override 
    public void init(ProcessingEnvironment env) { 
     interfaceToCheck = env.getElementUtils().getTypeElement("com.notnoop.myinterface").asType(); 
    } 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, 
      RoundEnvironment roundEnvironment) { 
     for (TypeElement e : 
      ElementFilter.typesIn(roundEnvironment.getRootElements())) { 
      if (this.processingEnv.getTypeUtils() 
        .isSubtype(e.asType(), interfaceToCheck) 
       && (!hasMethod(e, "equals", 0) 
        || !hasMethod(e, "hashCode", 0))) { 
       processingEnv.getMessager().printMessage(Kind.ERROR, 
        "Class " + e + " doesn't override hashCode or equals", e); 
      } 
     } 
     return true; 
    } 
} 

: 여기

당신이 원하는 검사를 수행 할 샘플 프로세서입니다 프로세서 이름 ( com.notnoop.CheckMethodOverride)이 들어있는 classpath에 추가하십시오. forlder META-INF은 프로젝트의 루트 소스 디렉토리 (또는 maven을 사용하는 경우 자원 디렉토리)에 살 수 있습니다.

모든 명령 줄 컴파일러에서 작동합니다. 내가 IDE에서 그것을 활성화하는 방법을 모르겠다.

+0

나는 이것을 완전히 이해하지는 못했지만 놀랍고, OP의 문제에 대한 우아한 해결책이 될 것입니다. +1. –

+0

+1 : 우아한 해결책 !!! 나는 그것을 시도 할 것이다 ... –

+0

이것은 주석에서 "클래스 리터럴을 런타임 유형 토큰으로 사용하는"좋은 예이다. http://java.sun.com/docs/books/tutorial/extra/generics/literals.html . 그것은 Neal Gafter의 "Super Type Tokens"를 연상케합니다. http://gafter.blogspot.com/2006/12/super-type-tokens.html – trashgod

1

나는 두려워서 물을 곳이 잘못되었습니다. 우리는 언어에 관한 질문에 답하고, 우리는 언어를 만들지 않습니다.

Sun은 개선 또는 완전한 버그보고를위한 제안을 할 수있는 커뮤니티 프로세스를 제공합니다. 네가 원한다면 나는 너를 파헤쳐 줄 수있어.

나는 그것이 끝나지 않을 것이라고 생각합니다. 지금까지 좋은 아이디어로 여겨지지 않았다면 아마 그렇지 않을 것입니다.

단기간에 도움이되는 것이 독립 실행 형 스타일 검사 프로그램 일 수 있습니다. CheckStyle이 마음에 듭니 다. 아마도 가장 큰 이름 일 것입니다. 맥주와 같이 자유롭고 다양한 옵션을 제공합니다. 나는 생각한다,하지만 난 hashCode()equals()을 구현 여부를가 너무 어딘가에있다 "고, 확실하지 않다

이 에게
+0

+1 : CheckStyle 링크에 대한 thx 나는 그것에 대해 들어 본 적이 없지만 ...이 경우 hashCode() 및 equals() 메서드를 만든 자기 생각은 더 적절할 것입니다 ... –

+0

운 좋게 Java/Sun은이를 강제 할 수있는 메커니즘을 제공했습니다! – notnoop

+0

칼, 나는 OP가 언어 변경을 원한다고 생각하지 않는다. 대신 그들은 존재하는 언어 내에서 해결책을 찾고자합니다. –

1

난 그냥 가능한 대안으로 생각했다.

사용자 인터페이스 (또는 아마도 추상적 인 방법) 방법을 지정할 수 있습니다 (예) equals2()hashCode2(). 이들은 물론, 인터페이스의 구현을 구현하는 필수가 될 것입니다. 당신은 이렇게 뭔가을 코딩 라이브러리 소비자를 강제 할 수있다.

그리고 당신의 라이브러리 클래스, 그 작업의 구현과 당신의 인터페이스는이 "custom"funct를 사용할 수 있습니다. 이온을 "실제"기능의 대체 또는 구현으로, 그리고 재 정의 자체에 적용합니다.

매우 세련된 개념은 아니며 매우 매끄럽지도 않지만 그 중 일부를 만들 수도 있습니다.

+0

+1 : thx !! 그것은 아주 좋은 리드입니다 ... –

2

인터페이스로 할 수는 없지만 추상 클래스로 할 수는 있습니다. 예 :

public interface Entity { 
    //... 
} 

public abstract class AbstractEntity implements Entity { 

    @Override 
    public abstract boolean equals(Object other); 

    @Override 
    public abstract int hashCode(); 

} 

과 그들이 Entity을 구현하고자 할 때마다 AbstractEntity을 확장하는 개발자를 말한다.

규칙을 실제로 적용하려면 Spring의 Bean 후 처리기와 같은 일종의 런타임 검사가 필요합니다.

+0

+1 : 그것은 내 첫 번째 생각이었습니다 ...하지만 나는 다른 클래스로부터 상속하는 개발자를위한 무료 옵션을 유지하고 싶었습니다 :) ...하지만 당신은 맞을 것 같습니다. way ... –

관련 문제