REPL에서 :type을 사용하면 타입을 볼 수 있다.
scala> :type if (true) println("true")
Unit
scala> :type if (true) true
AnyVal
scala> :type false
Boolean
scala> :type "aaa"
String
scala> Map(1->"1", 2->"3") map (_._2)
res7: scala.collection.immutable.Iterable[String] = List(1, 3)
scala> :type Map(1->"1", 2->"3") map (_._2)
scala.collection.immutable.Iterable[String]
scala> :type -v Map(1->"1", 2->"3") map (_._2)
// Type signature
scala.collection.immutable.Iterable[String]
// Internal Type structure
TypeRef(
TypeSymbol(
abstract trait Iterable[+A] extends Traversable[A] with Iterable[A] with GenericTraversableTemplate[A,scala.collection.immutable.Iterable] with IterableLike[A,scala.collection.immutable.Iterable[A]] with Parallelizable[A,scala.collection.parallel.immutable.ParIterable[A]]
)
args = List(
TypeRef(
TypeSymbol(
final class String extends Serializable with Comparable[String] with CharSequence
)
)
)
)
trait Trait {
val m = 1
}
class Clazz extends Trait {
var m1 = 333333
var m2 = "aa"
}
object Execise extends App {
val clazz = classOf[Clazz]
val name = clazz.getName
println("name : " + name)
//println
val constructors = clazz.getConstructors
println("constructors : " + constructors.mkString(" "))
println
val methods = clazz.getMethods
println("methods : " + methods.mkString(" "))
println
val fields = clazz.getFields
println("fields : " + fields.mkString(" "))
println
val annotations = clazz.getAnnotations
println("annotations : " + annotations.mkString(" "))
println
val superClass = clazz.getSuperclass
println("superClass : " + superClass)
println
val typeParameters = clazz.getTypeParameters
println("typeParameters : " + typeParameters.mkString(" "))
}
결과는 다음과 같다.
name : com.google.Clazz
constructors : public com.google.Clazz()
methods : public void com.google.Clazz.m1_$eq(int) public void com.google.Clazz.m2_$eq(java.lang.String) public int com.google.Clazz.m1() public java.lang.String com.google.Clazz.m2() public int com.google.SuperClazz.m() public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public java.lang.String java.lang.Object.toString() public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll()
fields :
\3 1aY8n"%QQ"
-!AC*va8 \1{u")QC1A(8jiz"a Aq!A!#ncU 1/5 QCC8-7b ARCAJ]RDqAA1$nc}#S-9}"F
1#AyIEBaA !BaA72A!9Aa
)AA73+1CA-A#BA+aM\4-
AA[1wC&Q'RN\4 =!Ca1QNM0%KF$"H r!aM!11Q!
1!!)
superClass : class com.google.SuperClazz
스칼라의 classOf의 리턴타입은 java.lang.Class이다.(컴파일러에서 제대로 생성된다)
def classOf[T]: Class[T] = null
또한, 결과를 통해 추측할 수 있겠지만, 일부 내용을 파싱하면서 에러난 부분이 발생했다. 아직 scala 클래스 객체를 완벽히 소화한 상태는 아니다. 이는 스칼라에서 쓸 수 있는 TypeTags를 활용하면 의미있는 정보를 얻을 수 있다.
먼저 스칼라의 ClassTag이다. ClassTag를 사용하면 컴파일러가 암시 ClassTag를 생성한다. TypeTags의 약한 버전이다.
import scala.reflect.ClassTag
case class Person(id: Int)
def makeArray[T: ClassTag] (elements: T*) = Array[T](elements: _*)
println(makeArray(1,2,3).mkString(" "))
println(makeArray("one", "two", "three").mkString(" "))
println(makeArray(1, "xxx").mkString(" "))
println(makeArray(Person(1), Person(2)).mkString(" "))
결과는 다음과 같다.
1 2 3
one two three
1 xxx
Person(1) Person(2)
다음은 TypeTag를 활용한 예시이다. 강력한 스칼라 reflection api이다.
class SuperClazz {
val m = 1
}
class Clazz extends SuperClazz {
var m1 = 333333
var m2 = "aa"
}
import scala.reflect.runtime.universe._
def toType[T: TypeTag](t : T) = typeOf[T]
println(toType(1))
println(toType(false))
println(toType(new Clazz))
println(toType(List(1, "aa")))
println(toType(Seq(1, true, 3.14)))
val t = toType(2)
println(t.typeSymbol)
println(t.erasure)
println(t.typeArgs)
println(t.baseClasses)
println(t.companion)
println()
val t1 = toType(new Clazz)
println(t1.members)
println(t1.baseClasses)
결과는 다음과 같다.
Int
Boolean
com.google.Clazz
List[Any]
Seq[AnyVal]
class Int
Int
List()
List(class Int, class AnyVal, class Any)
Int.type
Scope{
private[this] var m2: <?>;
def m2_=: <?>;
def m2: <?>;
private[this] var m1: <?>;
def m1_=: <?>;
def m1: <?>;
def <init>: <?>;
val m: <?>;
final def $asInstanceOf[T0](): T0;
final def $isInstanceOf[T0](): Boolean;
final def synchronized[T0](x$1: T0): T0;
final def ##(): Int;
final def !=(x$1: Any): Boolean;
final def ==(x$1: Any): Boolean;
final def ne(x$1: AnyRef): Boolean;
final def eq(x$1: AnyRef): Boolean;
final def notifyAll(): Unit;
final def notify(): Unit;
protected[package lang] def clone(): java.lang.Object;
final def getClass(): java.lang.Class[_];
def hashCode(): Int;
def toString(): java.lang.String;
def equals(x$1: Any): Boolean;
final def wait(): Unit;
final def wait(x$1: Long): Unit;
final def wait(x$1: Long,x$2: Int): Unit;
protected[package lang] def finalize(): Unit;
final def asInstanceOf[T0]: T0;
final def isInstanceOf[T0]: Boolean
}
List(class Clazz, class SuperClazz, class Object, class Any)
'scala' 카테고리의 다른 글
[scala] () => A라는 형식의 Thunk 예시 (0) | 2017.01.04 |
---|---|
[scala] 이항 함수를 사용하는 함수와 for 내장 함수 비교 (0) | 2017.01.04 |
[scala] 스칼라 스크립트 실행 코드 예시 (0) | 2016.12.16 |
[scala] 쉘 실행하기 (0) | 2016.12.13 |
[scala] 클래스 초기화하기(생성) (0) | 2016.12.13 |