2017-12-10 16 views
4

this question을 보면서 get 또는 set 사용 사이트에 @Throws을 적용해도 아무런 효과가 없습니다. 또한 @ 목표가 속성 인 경우 목표가 적용되지 않습니다.

, 유일하게 유효한 목표 @Throws에 대한AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTERAnnotationTarget.CONSTRUCTOR 있습니다.

JPA 주석 및 Deprecated과 같은 기타 특수 효과가 올바르게 적용되며 해당 메소드에 올바르게 적용됩니다.

이상한 행동입니다.

설명하기 위해 Java로 간단한 추상 클래스를 생성했습니다. 하나의 생성자, 하나의 메소드 및 하나의 get 메소드가 있습니다.

public abstract class JavaAbstractClass { 

    @Deprecated 
    @NotNull public abstract String getString() throws IOException; 
    public abstract void setString(@NotNull String string) throws IOException; 

    public abstract void throwsFunction() throws IOException; 

    public JavaAbstractClass() throws IOException { 
    } 

} 

모든 메소드/생성자는 IOException으로 표시됩니다.

그러나

, 내가 코 틀린에 해당하는 클래스를 작성 및 상호 운용성에 대한 throws에 적절한 방법을 표시하려고하면 발생 getStringsetString 방법은 더 throws 조항이 없습니다.

abstract class KotlinAbstractClass @Throws(IOException::class) constructor() { 

    @get:Deprecated("Deprecated") 
    @get:Throws(IOException::class) 
    @set:Throws(IOException::class) 
    abstract var string: String 

    @Throws(IOException::class) 
    abstract fun throwsFunction() 

} 

디 컴파일 코드 : 나에게

@Metadata(Some metadata here) 
public abstract class KotlinAbstractClass { 
    /** @deprecated */ 
    @Deprecated(
     message = "Deprecated" 
    ) // @Deprecated made it through! 
    @NotNull 
    public abstract String getString(); // Nothing here! 

    public abstract void setString(@NotNull String var1); // Nothing here! 

    public abstract void throwsFunction() throws IOException; 

    public KotlinAbstractClass() throws IOException { 
    } 
} 

, 이러한 내부 주석 대신 방법에 직접 적용되는 컴파일러에 의해 특별히 처리해야하기 때문에 것으로 보인다.

또한, 비 추상적 인 속성의 게터에 적용 :

val string: String 
@Throws(IOException::class) get() = "Foo" 

는 서명 public final String getString() throws IOException와 방법을 생성 않습니다!

아마도이 사례가 제대로 처리되지 않았습니까?

이것은 버그입니까?


참고 :이 메서드가 실제로이 예외를 throw하는지 여부와 관련이 없습니다.

내가 할 경우 :

@get:Throws(IOException::class) 
val string: String 
    get() = BufferedReader(FileReader("file.txt")).readText() 

컴파일 된 코드는 FileReader constructorFileNotFoundException 발생한다는 사실에도 불구하고 여전히

@NotNull 
public final String getString() { 
    return TextStreamsKt.readText((Reader)(new BufferedReader((Reader)(new FileReader("file.txt"))))); 
} 

입니다.

또한 구현을 가질 수없고 여전히 throws 절을 가질 수 있으므로 추상 메소드의 경우 중요하지 않습니다.

@tynn이 제안하고, 구체적인 구현이 추가로 내가 할 경우

class ConcreteClass : KotlinAbstractClass() { 

    override val string: String 
     get() = BufferedReader(FileReader("file.txt")).readText() 

    ... 

} 

나는 여전히 같은 결과를 얻을 수 있습니다.

override val string: String 
     @Throws(FileNotFoundException::class) get() = BufferedReader(FileReader("file.txt")).readText() 

이는 서명 당신에게 throws에 적절한 Java 버전을 제공한다 : 나는 @tynn 믿을

+0

실제로이 예외를 발생시키는 getter 또는 setter를 구현해보십시오. 코드가 안전하다면, 오버라이드 한 것에 대한'throws' 선언을 재 선언 할 필요가 없습니다. 어쩌면 _Kotlin_은'@ Throws' 어노테이션으로 똑똑 할 수도 있습니다. – tynn

+0

@ tynn 질문을 수정하겠습니다. – Moira

답변

2

는 다음과 같이 제안한다. 나는 추론 것 같다 당신은 할 경우이 :

@get:Throws(IOException::class) 
val foo: String = "foo" 

컴파일러는 당신이 그것을 무시 적이 있기 때문에, IOException를 throw하는 게터에서 아무것도 볼 수있을만큼 똑똑하다, 그래서 원 ' throws 섹션을 생성하십시오. getter가 오버라이드되면 컴파일러는 제공 한 코드가 throw 할 수있는 코드를 알 수 없으므로 주석을 따르고 항상 throws 부분을 출력합니다.

abstract class KotlinAbstractClass { 

    abstract var string: String 
     @Throws(IOException::class) get 
     @Throws(IOException::class) set 
} 

그것을 자세히 살펴 본다 후,이 경우 작동하지 않을 @get:Throws(IOException::class)에 대한 이유를 볼 :

UPDATE는

다음은 올바른 바이트 코드를 생성하는 것 같다. YouTrack for Kotlin에 문제를 제기하고 팀 구성원이 그것에 대해 이야기해야하는 것을 볼 수 있습니다.

+0

아니요, 제 질문에서 두 부분을 모두 다루었습니다.'@ Throws'를 _any_ getter에 직접 두었습니다. 던지지 않았더라도'throws' 절이 추가되었습니다. @get : Throws를 _any_ 속성에 두는 것은 효과가 없습니다. 만약 당신이 제안한대로'val string : String @Throws (IOException :: class) get() = "Foo"', "컴파일러는 getter에 IOException을 던질 것이 아무것도 없다는 것을 알만큼 똑똑하다" throws 절이 생성되기 때문에 불가능합니다. – Moira

+0

실무 솔루션으로 내 대답을 업데이트했습니다. – Egor

+1

오, 나는 그 가능성에 대해 잊어 버렸습니다. 사용 사이트 특수 효과가 작동해야하는 것처럼 보인다고 동의합니다. 가능하면 할 수 있습니다. 감사! – Moira