E169: TargetName On Top-Level Class — 최상위 클래스에 붙은 @targetName
E169: TargetName On Top-Level Class — 최상위 클래스에 붙은 @targetName
@targetName 애노테이션을 최상위 클래스·트레이트·객체에 적용할 때 발생하는 에러예요.
본문
@targetName 애노테이션은 주로 상호운용성(interoperability)을 위해 생성된 바이트코드에서 정의에 대체 이름을 붙여주는 데 쓰여요. 그런데 최상위 타입 정의에는 적용할 수 없어요. 왜냐하면 바이트코드의 클래스 이름이 파일명과 패키지 구조와 일치해야 하기 때문이죠.
예시 (Example)
import scala.annotation.targetName
@targetName("Foo") class MyClass
에러 (Error)
-- [E169] Syntax Error: example.scala:3:25 -------------------------------------
3 |@targetName("Foo") class MyClass
| ^
| @targetName annotation not allowed on top-level class MyClass
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| The @targetName annotation may be applied to a top-level val or def, but not
| a top-level class, trait, or object.
|
| This restriction is due to the naming convention of Java classfiles, whose filenames
| are based on the name of the class defined within. If @targetName were permitted
| here, the name of the classfile would be based on the target name, and the compiler
| could not associate that classfile with the Scala-visible defined name of the class.
|
| If your use case requires @targetName, consider wrapping class MyClass in an object
| (and possibly exporting it), as in the following example:
|
| object Wrapper:
| @targetName("Foo") class MyClass { ... }
|
| export Wrapper.MyClass // optional
-----------------------------------------------------------------------------
해결 방법 (Solution)
import scala.annotation.targetName
// @targetName can be used on methods and vals
class MyClass {
@targetName("addOne") def ++(x: Int): Int = x + 1
}
import scala.annotation.targetName
// Wrap in an object if you need targetName on a class
object Wrapper {
@targetName("FooClass") class MyClass
}
더 알아보기
@targetName은 메서드나 val에는 언제든 붙일 수 있어요. 클래스에 꼭 필요하다면 객체 안에 감싸고 export로 꺼내 쓰는 방법을 권장해요.