'asInstanceOf'에 해당되는 글 1건

  1. 2009.11.22 Scala 주의사항

Scala 주의사항

Scala 2009. 11. 22. 21:37

클래스 객체 사용하기

Java 에서는 클래스 객체를 쓰려면 String.class 같은 식으로 쓴다. Scala는 이 문법을 쓰지 않고 아래처럼 한다.

val cls = classOf[String] ;

타입명을 []안에 쓰게하여 언어의 다른 요소와 일관성을 맞추려 한 것 같다. 하지만 개인적으로는 Java문법이 더 편하다.

캐스팅하기, 특정 타입인지 검사하기

Java에서는 캐스팅할 때 C와 같은 문법을 쓰는데 Scala는 아래처럼 한다.

// 특정 객체를 String 타입으로 캐스팅
val str = someObj.asInstanceOf[String];

캐스팅 문법은 Scala가 더 좋다.

객체가 특정 타입인지 검사할 때 Java는 instanceof연산자를 쓴다.

if( someObj instanceof Integer ) {
    Integer i = (Integer)someObj ;
    System.out.println(i*i) ;
}
else {
    // Integer가 아닌 경우 처리
}

Scala에는 instanceof에 해당하는게 없고 패턴매칭을 쓴다.

someObj match {
    case i:Int => println (i*i)
    case _ => // Int가 아닌 경우 처리
}

이것 역시 Scala가 더 낫다.

Annotation

아래의 Java 어노테이션을 Scala에서 쓴다고 해보자.

package test;
import java.lang.annotation.*;
@Target({ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface ConsAnnotation {
}

이 어노테이션을 아래 class의 생성자에 붙이려면 아래처럼 하면 될 것 같다.

package test
@ConsAnnotation
class TargetClass1 (num:Int){
}

컴파일해보면 잘 된다. 하지만 아래코드를 실행해보면

package test
object Run1 {
    def main(args:Array[String]) {
        val cls = classOf[TargetClass1] ;
        println(cls + " ==> " + cls.getAnnotation(classOf[ConsAnnotation])) ;
        cls.getConstructors().foreach{ cons =>
            println(cons + " ==> " + cons.getAnnotation(classOf[ConsAnnotation])) ;
        }
    }
}

뭔가 문제가 있음을 알 수 있다.

        class test.TargetClass1 ==> @test.ConsAnnotation()
        public test.TargetClass1(int) ==> null
        

이렇게 하면 생성자가 아니라 클래스에 어노테이션이 붙는다. 생성자에 붙이려면 아래처럼 클래스명과 매개변수 리스트 사이에 어노테이션을 넣어야 한다. 그리고 어노테이션에 매개변수를 넣지 않더라도 ()를 꼭 붙여야 한다.(안 붙이면 컴파일 오류가 난다.)

package test
class TargetClass2 @ConsAnnotation()(num:Int ){
}
        class test.TargetClass2 ==> null
        public test.TargetClass2(int) ==> @test.ConsAnnotation()
        

이 어노테이션은 생성자에만 붙도록 되어있음에도 클래스에 붙일 수 있다는 것은 뭔가 이상하다. 내가 확인해본 바로는 scalac는 어노테이션의 Target설정을 확인하지 않는다고 한다.

Posted by lispholic
,