문제

메소드에 주석을 달 수있는 방법이 있습니까?

@MagicAnnotation
// no throws clause!
void foo()
{
  throw new Exception("bar")'
}
도움이 되었습니까?

해결책

그렇게 할 방법이 없습니다. 적어도 지금은 이와 같은 해결 방법을 사용합니다 (단순화).

@SuppressWarnings({"rawtypes", "unchecked"})
public class Unchecked {
    public static interface UncheckedDefinitions{
        InputStream openStream();
        String readLine();
            ...
    }

  private static Class proxyClass = Proxy.getProxyClass(Unchecked.class.getClassLoader(), UncheckedDefinitions.class);

    public static UncheckedDefinitions unchecked(final Object target){
        try{
            return (UncheckedDefinitions) proxyClass.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler(){
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if (target instanceof Class){
                        return MethodUtils.invokeExactStaticMethod((Class) target, method.getName(), args);
                    }

                  return MethodUtils.invokeExactMethod(target, method.getName(), args);
                }
            });
        }
        catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}

그리고 사용법은 다음과 같습니다.

import static ....Unchecked.*;

...

Writer w = ...;
unchecked(w).write(str, off, len);

속임수는 인터페이스가 "완료되지 않았다"는 것입니다. 어딘가에 확인되지 않은 메소드가 필요할 때마다 해당 객체를 확인하지 않고 IDE가 인터페이스에서 메소드 서명을 생성하도록하겠습니다.

그런 다음 구현은 일반적인 것입니다 (반사 및 "느린"그러나 일반적으로 충분히 빠릅니다)

일부 코드 포스트 프로세서 및 바이트 코드 위버가 있지만 현재 프로젝트에는 불가능했습니다 (AOP 또는 기타 JVM 기반 언어조차도 없음). 그래서 이것은 "발명"되었습니다.

다른 팁

프로젝트 Lombok 's @SneakyThrows 아마도 당신이 찾고있는 것일 것입니다. 실제로 예외를 감싸는 것이 아니라 (많은 경우에 문제가 될 수 있기 때문에) 편집 중에 오류가 발생하지 않습니다.

@SneakyThrows
void foo() {
    throw new Exception("bar")'
}

당신은 SAGONT 로이 작업을 수행 할 수 있습니다. JoinPoint (이 경우 메소드 FOO의 호출)을 선언하고 예외를 '연화'합니다.

편집하다 이것에 대해 조금 자세히 설명하기 위해 :

다음 수업이 있다고 가정 해 봅시다 Bar:

public class Bar {

    public void foo() throws Exception {
    }
}

... 그리고 당신은 다음과 같은 테스트를 받았습니다.

import junit.framework.TestCase;

public class BarTest extends TestCase {

    public void testTestFoo() {
        new Bar().foo();
    }
}

그런 다음 분명히 테스트가 컴파일되지 않습니다. 오류가 발생합니다.

Unhandled exception type Exception  BarTest.java(line 6)

이제 이것을 측면으로 극복하기 위해 매우 간단한 측면을 작성합니다.

public aspect SoftenExceptionsInTestCode {

    pointcut inTestCode() : execution(void *Test.test*());

    declare soft : Exception : inTestCode();
}

측면은 기본적으로 테스트 내의 모든 코드 (즉 : 예외를 던지는 "테스트"로 끝나는 클래스에서 "테스트"로 시작하는 메소드)는 AspectJ 컴파일러에 의해 수락되어야한다고 말합니다. 예외가 발생하면 래핑하고 던져집니다. RuntimeException AspectJ 컴파일러에 의해.

실제로,이 테스트를 Eclipse (AJDT 설치 포함) 내에서 SageJ 프로젝트의 일부로 실행하면 테스트가 성공하는 반면 측면이 없으면 컴파일하지 않습니다.

바이트 코드 리엔지니어링, 맞춤형 컴파일러 또는 측면 지향 프로그래밍이 가능하다고 생각합니다.1. Java와는 반대로 C#은 예외를 확인하지 않았습니다.2.

확인 된 예외를 억제하고 싶은 이유를 물어봐도 될까요?

1 ~에 따르면 Maarten Winkels 이것은 가능하다.
2 그리고 일부 채널 9 비디오에 따르면 그들은 확인 된 것들을 소개하는 것에 대해 생각하고 있습니다.

편집하다: 질문의 경우 : 방법을 확인하여 점검 된 예외 억제의 후보자가되도록 메소드를 표시 할 수 있습니다. 그런 다음 컴파일 시간 또는 런타임 트릭을 사용하여 실제 억제 / 포장을 적용합니다.

그러나, 당신의 사건 주위의 환경을 보지 못하기 때문에, 이러한 방식으로 예외를 마무리하면 해당 방법의 고객을 혼동 할 수 있습니다. 그들은 runtimeexception을 처리 할 준비가되지 않을 수 있습니다. 예를 들어 :이 메소드는 IOException을 던지고 클라이언트는 오류 대화 상자를 표시하기 위해 FILENOTFoundException으로 포착합니다. 그러나 예외를 runtimeexception으로 raped하면 오류 대화 상자가 표시되지 않으며 아마도 발신자 스레드도 죽일 수 있습니다. (IMHO).

확인 된 예외는 메소드 구현의 책임입니다. 이 사실을 매우 신중하게 받아들이십시오. 이와 같은 해결 방법 아티팩트를 사용할 수없는 경우.

어떤 경우 에도이 작업을 수행 할 수 있습니다. Class.newInstance 하지 않습니다Exception an InvocationTargetException; 오히려 그것은 그것을 던진다 아무 말 않고:

class ExUtil {
  public static void throwSilent(Exception e) { //NOTICE NO THROWS CLAUSE
      tl.set(e);
      SilentThrower.class.newInstance(); //throws silently
  }

  private static ThreadLocal<Exception> tl = new ThreadLocal<Exception>();
  private static class SilentThrower {
      SilentThrower() throws Exception {
          Exception e = tl.get();
          tl.remove();
          throw e;
      }
  }
}

그런 다음이 유틸리티를 어디서나 사용할 수 있습니다.

ExUtil.throwSilent(new Exception());
//or
try {
  ioMethod();
} catch (IOException e) { ExUtil.throwSilent(e); }

그건 그렇고, 이것은입니다 정말 나쁜 생각 :-)

Eclipse의 완료 / 템플릿 시스템을 사용하여 모든 코드 블록을 쉽게 포장합니다.

여기 내 템플릿이 있습니다.

try { // Wrapp exceptions

${line_selection}${cursor}

} catch (RuntimeException e) { // Forward runtime exception
throw e;
} catch (Exception e) { // Wrap into runtime exception
throw new RuntimeException(
    "Exception wrapped in #${enclosing_method}", 
    e); 
}

Java 8을 사용하면 다음과 같이 쉽습니다. soften(() -> methodThatMayThrow())

더 읽어보십시오 http://iirekm.blogspot.com/2014/05/fix-problems-with-java-checked.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top