2015-08-16 2 views
0

Попытка получить значения всех полей ребенка от родительского класса, как это:Scala: Получить значение ребенка от родителя?

 for (field <- this.getClass.getDeclaredFields) { 
      Logger.debug(field.getName) 
      field.get(this) 
     } 

и получил ошибку

Исключение: Класс models.Model $$ anonfun $ 4 не может получить доступ к члену класс models.Good с модификаторами "частный" на линии

field.get(this) 

в хорошем классе У меня нет частных полей:

class Good(id: Option[String]) extends Model[realGood](id){ 
    lazy val title: String = this.load[String](realObject.get.title) 
    lazy val cost: Double = this.load[Double](realObject.get.cost) 
} 

Что не так с этим кодом?

+0

В какой строке указывается сообщение об ошибке? Я думаю, что просмотр класса Scala с помощью отражения Java может быть опасным, поскольку, когда Scala компилируется в байт-код, компилятор выполняет множество грязных трюков, чтобы быть совместимыми с байт-кодом Java. Вместо этого вы должны использовать отражение Scala. – Dici

+0

Скорее всего, «это» неправильно. Вы можете быть в пределах функции, и 'this' является анонимным внутренним классом класса, который вы хотели бы получить. BTW, в Scala каждое поле является закрытым, можно изменять только видимость методов доступа и модификатора. –

ответ

1

Как указано в комментариях, преобразование Scala в java-байт-код не всегда прямолинейно (хотя обычно это довольно предсказуемо, как только вы получаете его). В частности, открытые поля в Scala компилировать в частную область с общественным добытчиком в Java байткоде:

fukaeri:~ dlwh$ cat zzz.scala 
class Good(id: Option[String]) { 
    lazy val title: String = ??? 
    lazy val cost: Double = ??? 
} 

fukaeri:~ dlwh$ scalac zzz.scala 
fukaeri:~ dlwh$ javap -private Good 
Compiled from "zzz.scala" 
public class Good { 
    private java.lang.String title; 
    private double cost; 
    private volatile byte bitmap$0; 
    private java.lang.String title$lzycompute(); 
    private double cost$lzycompute(); 
    public java.lang.String title(); 
    public double cost(); 
    public Good(scala.Option<java.lang.String>); 
} 

Вы можете видеть, что Good имеет частные поля для каждого из объявленных открытых полей, в дополнении к государственным добытчикам. Поскольку поля lazy val, они также имеют методы вычисления для инициализации, и есть поле bitmap$0, чтобы гарантировать, что ленивые vals инициализируются только один раз.

В вашей петле вы можете использовать field.setAccessible(true), чтобы исправить свое исключение.

Смежные вопросы