找不到 Scala 扩展特征字段

Scala extend trait field not found

我有一个带有 public UUID 的 scala trait,它有一个默认值:

trait pet {
    var uuid_ : UUID = UUID.randomUUID
}

现在我正在创建多个 类,也在 scala 中:

class dog extends pet {
    var foo = 1
}
class cat extends pet {
}
class fish extends pet {
}

之后我在Java(混合两种语言的旧项目)中创建了一个方法。
在这里,我的问题被剪掉了。在变量 somePet 中是 dogcatfish 的实例。但不清楚具体是什么:

// printing all variables in the console for human testing
Serializer.printAllFields(somePet);

// The somePet Variable must be a pet
if(!pet.class.isAssignableFrom(somePet.getClass()))
    throw new Exception("Not a pet.");

// get the UUID of the pet
UUID uuid_;
try {
    Field f = pet.class.getField("uuid_");
    f.setAccessible(true);
    uuid_ = (UUID) f.get(somePet);
}catch(Exception e){
    // no uuid found
    throw e;
}

但是当我 运行 代码时,我得到以下错误:

Exception in thread "main" java.lang.NoSuchFieldException: uuid_

并且堆栈跟踪指向 Field f = pet.class.getField("uuid_");
但是代码有什么问题?
我认为的另一种选择是将这一行替换为:

Field f = ntObj.getClass().getField("uuid_");

但这也失败了。
那么变量uuid_在哪里呢?
因为当我使用序列化程序在当前 somePet 的控制台中打印出所有变量时,我得到类似

的内容
* cat.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;

* dog.foo = 1
* dog.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;

在控制台中。
所以变量 uuid_ 有一个默认值。
(我正在使用来自 this post 的序列化器)

那么如何在我的 java 片段中获取 uuid_ 变量?

首先,java.util包下没有这个Serializer,所以你用的是别的东西

trait 被翻译成 Java interface本身不能有字段
但是,您正在尝试通过 Pet 界面

访问该字段
pet.class.getField(...)

那不行。你需要在具体class.
里面找字段 此外,该字段默认为 private,因为访问权限是通过 getter.

授予的

getField 方法能够检索整个 class 层次结构(这意味着甚至是超级classes)的每个 public 字段,而 getDeclaredField 能够检索 protectedprivate 字段,但只能在您调用它的确切 class 上。您还需要调用 setAccessible(true),因为

A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks

正确的代码是(dog是具体实例)

final Field uuid = dog.getClass().getDeclaredField("uuid_");
uuid.setAccessible(true);
final Object o = uuid.get(dog);

或使用自动 getter

final Method uuid = dog.getClass().getMethod("uuid_");
final Object o = uuid_.invoke(dog);