복붙노트

[SCALA] 케이스 클래스의 필드 이름의 목록을 가져옵니다

SCALA

케이스 클래스의 필드 이름의 목록을 가져옵니다

나는 경우 클래스의 필드 이름을 얻을 필요가있다. 나는 그것의 가치에 관심이 아니에요. 나는 필드 이름의 목록을 반환 getClass.getDeclaredFields.map (_. 대한 getName) 생각했다.

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)

이 사용자 $의 .MODULE의 $는 무엇입니까? 그게 뭔데?

당신이 경우 클래스의 인스턴스를 가지고 있지만 난 단지 필드를 얻기 위해 인스턴스를 생성하지 않으려는 경우 방법 getDeclaredFields 잘 작동합니다.

왜이 사실이 아니다 : User.getClass.getDeclaredFields.map (_. getName) == 목록 ( "ID", "이름")?

해결법

  1. ==============================

    1.User.getClass를 사용하면 클래스 동반자 언급하는 기본적으로 스칼라 경우 클래스 자체를 경우 클래스의 생성, 그리고 그 객체. 케이스 클래스의 클래스 객체를 얻으려면, classOf [사용자]를 사용하세요.

    User.getClass를 사용하면 클래스 동반자 언급하는 기본적으로 스칼라 경우 클래스 자체를 경우 클래스의 생성, 그리고 그 객체. 케이스 클래스의 클래스 객체를 얻으려면, classOf [사용자]를 사용하세요.

    양자 택일로, 당신은 당신에게 더 많은 정보를 제공하는 경우 클래스의 메타 데이터를 얻기 위해 스칼라의 반사 API를 사용할 수 있습니다 :

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

    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)
    
  2. ==============================

    2.스칼라 2.13부터 (제품의 구현이다)의 경우 클래스는 이제 필드의 이름 반복자를 반환하는 productElementNames 방법으로 제공됩니다.

    스칼라 2.13부터 (제품의 구현이다)의 경우 클래스는 이제 필드의 이름 반복자를 반환하는 productElementNames 방법으로 제공됩니다.

    하나는 필드의 목록을 검색 할 수있는 경우 클래스의 인스턴스에서 (: : 문자열, 세 지능이)의 대소 클래스 사람 (이름 가정 해 봅시다)

    Person("hello", 28).productElementNames.toList
    // List[String] = List(name, age)
    
  3. ==============================

    3.User.getClass 당신에게 자바에서 User.class의 동등 제공하지 않습니다,하지만 당신에게 사용자 클래스의 동반자 객체의 클래스를 제공합니다. 당신은 classOf [사용]을 가지고있는 사용자의 Class 객체를 검색 할 수 있습니다.

    User.getClass 당신에게 자바에서 User.class의 동등 제공하지 않습니다,하지만 당신에게 사용자 클래스의 동반자 객체의 클래스를 제공합니다. 당신은 classOf [사용]을 가지고있는 사용자의 Class 객체를 검색 할 수 있습니다.

    편집 : 아, 그리고 사용자 $의 .MODULE $으로 내부적으로 사용되는 싱글 인스턴스에 접근합니다. 당신이 자바에서 싱글을 작성할 때 MyClass.INSTANCE에 동등이라고 생각.

  4. ==============================

    4.일부 스칼라 반사 코드가 더 이상 컴파일되지 않는 이유도 궁금, 여기에 좋은 똑똑한 '(. 분명히, 약 년 기원전 1300 년경부터 정확히 같은 방법으로 일하고있다) 자바 반사와 원유 솔루션입니다 :

    일부 스칼라 반사 코드가 더 이상 컴파일되지 않는 이유도 궁금, 여기에 좋은 똑똑한 '(. 분명히, 약 년 기원전 1300 년경부터 정확히 같은 방법으로 일하고있다) 자바 반사와 원유 솔루션입니다 :

    case class User(b: Int, a: String)
    val u = User(42, "JohnDoe")
    
    classOf[User]
    .getDeclaredFields
    .map{ f => 
      f.setAccessible(true)
      val res = (f.getName, f.get(u))
      f.setAccessible(false)
      res
    }
    

    그것은 이름과 값을 모두 얻을 것이다 :

    Array((b,42), (a,bob))
    

    순서는 생성자와 동일 할 것으로 보인다.

  5. ==============================

    5.당신이 불꽃을 사용하는 경우이 가장 쉬운 방법은 필드를 얻을 수 있습니다 :

    당신이 불꽃을 사용하는 경우이 가장 쉬운 방법은 필드를 얻을 수 있습니다 :

    val cols = Seq(CaseClassModel()).toDF().columns
    

    참고 : CaseClassModel이 필드를 초기화해야

  6. from https://stackoverflow.com/questions/31189754/get-field-names-list-from-case-class by cc-by-sa and MIT license