E201: Non-Named Argument in Java Annotation
E201: Non-Named Argument in Java Annotation
이 에러는 Java로 정의된 애노테이션에 위치(이름 없는) 인자를 사용할 때 발생해요. Scala 3.6.0부터 모든 Java 애노테이션에는 이름 있는 인자(named argument)가 필수예요.
본문
Java 애노테이션은 Scala에서 정확한 생성자 표현을 갖지 않아요. 그래서 예전 컴파일러는 위치 인자를 맞추기 위해 애노테이션 필드의 순서에 의존했어요. 이 방식은 취약한데, Java에서 애노테이션 필드의 순서를 바꾸는 것은 바이너리 호환은 되지만 위치 인자의 의미를 조용히 바꿀 수 있기 때문이에요.
예시 (Example)
class Foo:
@Deprecated("reason")
def oldMethod(): Unit = ()
에러 (Error)
-- [E201] Syntax Error: example.scala:2:14 -------------------------------------
2 | @Deprecated("reason")
| ^^^^^^^^
| Named arguments are required for Java defined annotations
| This can be rewritten automatically under -rewrite -source 3.6-migration.
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| Starting from Scala 3.6.0, named arguments are required for Java defined annotations.
| Java defined annotations don't have an exact constructor representation
| and we previously relied on the order of the fields to create one.
| One possible issue with this representation is the reordering of the fields.
| Lets take the following example:
|
| public @interface Annotation {
| int a() default 41;
| int b() default 42;
| }
|
| Reordering the fields is binary-compatible but it might affect the meaning of @Annotation(1)
|
-----------------------------------------------------------------------------
해결 방법 (Solution)
Java 애노테이션을 적용할 때 이름 있는 인자를 사용해요.
class Foo:
@Deprecated(since = "reason")
def oldMethod(): Unit = ()
대안으로, -rewrite -source 3.6-migration을 붙여 컴파일하면 위치 인자를 이름 있는 인자로 자동 변환해 주는 자동 재작성 기능을 이용할 수 있어요.