【问题标题】:Scala extend trait field not foundScala 扩展特征字段未找到
【发布时间】:2019-02-23 10:26:40
【问题描述】:

我有一个具有默认值的公共 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 sn-p 中获取 uuid_ 变量?

【问题讨论】:

    标签: java scala reflection traits


    【解决方案1】:

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

    trait 被转换为 Java interface,它本身不能有字段
    但是您正尝试通过Pet 接口访问该字段

    pet.class.getField(...)
    

    那是行不通的。您需要在混凝土内寻找字段class
    此外,该字段默认为private,因为访问权限是通过getter 授予的。

    getField 方法能够检索整个类层次结构(甚至是超类)的每个 public 字段,而 getDeclaredField 能够检索 protectedprivate 字段,但仅限于您从中调用它的确切课程。您还需要致电setAccessible(true),因为

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

    正确的代码是(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);
    

    【讨论】:

    • 我会提到 getDeclaredFieldgetField 的区别
    • 太好了,谢谢。不知道getDeclaredFieldgetField的区别。
    猜你喜欢
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2012-12-11
    相关资源
    最近更新 更多