我有一个带有默认值的公用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
中是dog
,cat
或fish
的实例。但尚不清楚它们到底是什么:
// 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_
变量?
答案 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