找不到Scala扩展特征字段

时间:2019-02-23 10:26:40

标签: java scala reflection traits

我有一个带有默认值的公用UUID的scala特性:

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_变量?

1 个答案:

答案 0 :(得分:6)

首先,软件包Serializer下没有这样的java.util,所以您要使用其他东西。

trait转换为Java interface,Java 本身没有字段
但是,您正在尝试通过Pet界面访问该字段

pet.class.getField(...)

那行不通。您需要在具体的class中查找字段。
另外,由于通过private授予访问权限,因此默认情况下该字段为getter

getField方法能够检索整个类层次结构的每个public字段(这甚至意味着超类),而getDeclaredField则能够检索protected和{ {1}}字段,但仅在您要从中调用的确切类上。您还需要致电private,因为

  

值为true表示反射对象应抑制   使用Java语言时进行访问检查。值为false表示所反射的对象应执行Java语言访问检查

正确的代码应该是(setAccessible(true)是具体实例)

dog

或使用自动final Field uuid = dog.getClass().getDeclaredField("uuid_"); uuid.setAccessible(true); final Object o = uuid.get(dog);

getter