Ottieni l’elenco dei nomi dei campi da case class

Ho bisogno di ottenere solo i nomi dei campi di case class. Non sono interessato ai suoi valori. Pensavo che getClass.getDeclaredFields.map(_.getName) avrebbe restituito un elenco di nomi di campi.

 scala> case class User(id: Int, name: String) defined class User scala> User.getClass.getDeclaredFields res14: Array[java.lang.reflect.Field] = Array(public static final User$ User$.MODULE$) scala> User.getClass.getDeclaredFields.toList res15: List[java.lang.reflect.Field] = List(public static final User$ User$.MODULE$) scala> val user = User(1, "dude") user: User = User(1,dude) scala> user.getClass.getDeclaredFields.toList res16: List[java.lang.reflect.Field] = List(private final int User.id, private final java.lang.String User.name) 

Cos’è questo $ utente $ .MODULE $? Cos’è quello?

Metodo getDeclaredFields funziona correttamente quando si ha un’istanza di una class del caso, ma non voglio creare un’istanza per ottenere solo i campi.

Perché questo non è vero: User.getClass.getDeclaredFields.map(_.getName) == List("id", "name") ?

Usando User.getClass , ci si riferisce all’object compagno di class che Scala per impostazione predefinita crea per la class case e non per la class case stessa. Per ottenere l’object class della class case, utilizzare classOf[User] .

In alternativa, è ansible utilizzare l’API di reflection di Scala per ottenere i metadati di una class di case, che fornisce molte più informazioni:

 import scala.reflect.runtime.universe._ def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect { case m: MethodSymbol if m.isCaseAccessor => m }.toList 

Test nella console sbt:

 scala> case class User(name: String, age: Int) defined class User scala> classAccessors[User] res0: List[reflect.runtime.universe.MethodSymbol] = List(value age, value name) 

User.getClass non fornisce l’equivalente di User.class in Java, ma fornisce la class dell’object companion della class User . È ansible recuperare l’object Class User con classOf[User] .

modifica : Oh e l’ User$.MODULE$ è un accessorio per l’istanza singleton che viene utilizzata internamente. Consideralo come l’equivalente di MyClass.INSTANCE quando stai scrivendo singleton in Java.