Scala-эквивалент Java java.lang.Class <T> Object

147

Вопрос лучше всего объясняется примером:

В Java для JPA EntityManager я могу сделать следующее (Учетная запись - мой класс Entity):

Account result = manager.find(Account.class, primaryKey);

В Scala моя наивная попытка:

val result = manager.find(Account.class, primaryKey)

Но когда я пытаюсь использовать Account.class в Scala, похоже, это не так. Как я могу указать объект java.lang.Class для класса Account в Scala?

  • 0
    VonC уже предоставил ответ, но взгляните на мой собственный вопрос / ответ по Scala & Erasure. Я думаю, что это может дать вам идеи сделать что-то не так, как вы пытаетесь.
Теги:
class

2 ответа

234
Лучший ответ

В соответствии с " Scala Система типов",

val c = new C
val clazz = c.getClass              // method from java.lang.Object
val clazz2 = classOf[C]             // Scala method: classOf[C] ~ C.class
val methods = clazz.getMethods      // method from java.lang.Class<T>

Метод classOf[T] возвращает представление времени выполнения для типа Scala. Это аналогично выражению Java T.class.
Использование classOf[T] удобно, если у вас есть тип, о котором вы хотите получить информацию, в то время как getClass удобен для извлечения той же информации из экземпляра типа.

Однако classOf[T] и getClass возвращают несколько разные значения, отражающие эффект стирания типа на JVM, в случае getClass.

scala> classOf[C]
res0: java.lang.Class[C] = class C

scala> c.getClass
res1: java.lang.Class[_] = class C

Вот почему не работает:

val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]

val integerClass: Class[Integer] = new Integer(5).getClass //similar error

Существует билет в отношении типа возврата getClass.

(Джеймс Мур сообщает, что билет "сейчас", т.е. ноябрь 2011 года, через два года, исправлен.
В 2.9.1 теперь getClass делает:

scala> "foo".getClass 
       res0: java.lang.Class[_ <: java.lang.String] = class java.lang.String

)

Еще в 2009 году:

Было бы полезно, если бы Scala обрабатывал возврат из getClass() как java.lang.Class [T] forSome {val T: C}, где C - это что-то вроде стирания статического типа выражение, на которое getClass называется

Это позволило бы мне сделать что-то вроде следующего, где я хочу наследовать класс, но не нуждаюсь в экземпляре класса.
Я также хочу ограничить типы классов, на которые я хочу наследовать, поэтому я использую Class [_ <: Foo]. Но это мешает мне проходить в классе Foo с помощью Foo.getClass() без трансляции.

Примечание: в отношении getClass возможным обходным путем будет:

class NiceObject[T <: AnyRef](x : T) {
  def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}

implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)

scala> "Hello world".niceClass                                       
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
  • 4
    К вашему сведению, билет @VonC был отмечен как исправленный 22 июня / 11. В 2.9.1 getClass теперь выполняет: scala> "foo" .getClass res0: java.lang.Class [_ <: java.lang.String] = класс java.lang.String
42

classOf[Account] в Scala эквивалентно Account.class в Java.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню