Для productElement не будет использоваться отражение. Это трюк с компилятором. Добавление case до того, как класс не просто создает сопутствующий объект (с методом apply и т. Д., См. http://www.scala -lang.org / node / 258 ), он также расширяет класс из признака Product , Компилятор создает реализации абстрактных методов productArity и productElement.
Вывод scalac -print Foo.scala
показывает это:
... case class Foo extends java.lang.Object with ScalaObject with Product {
...
override def productArity(): Int = 3;
override def productElement(x$1: Int): java.lang.Object = {
<synthetic> val temp6: Int = x$1;
(temp6: Int) match {
case 0 => {
Foo.this.v1()
}
case 1 => {
scala.Int.box(Foo.this.v2())
}
case 2 => {
Foo.this.v3()
}
case _ => {
throw new java.lang.IndexOutOfBoundsException(scala.Int.box(x$1).toString())
}
}
};
...
}
Если вы хотите получить доступ к полям без отражения, вы можете использовать метод productElement из признака Product
scala> case class Foo(v1: String, v2: Int, v3: Any)
defined class Foo
scala> val bar = Foo("Moin", 77, null)
bar: Foo = Foo(Moin,77,null)
scala> bar.productElement(0)
res4: Any = Moin
scala> bar.productElement(1)
res5: Any = 77
scala> bar.productElement(2)
res6: Any = null