chr*_*007 2 java reflection scala traits
我有一个scala特征,其公共UUID具有默认值:
trait pet {
var uuid_ : UUID = UUID.randomUUID
}
Run Code Online (Sandbox Code Playgroud)
现在我在scala中创建了多个类:
class dog extends pet {
var foo = 1
}
class cat extends pet {
}
class fish extends pet {
}
Run Code Online (Sandbox Code Playgroud)
之后我在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;
}
Run Code Online (Sandbox Code Playgroud)
但是当我运行代码时,我收到以下错误:
Exception in thread "main" java.lang.NoSuchFieldException: uuid_
Run Code Online (Sandbox Code Playgroud)
并且堆栈跟踪指向该行Field f = pet.class.getField("uuid_");.
但是代码有什么问题?
我认为另一种替代方法是用以下内容替换以下内容
Field f = ntObj.getClass().getField("uuid_");
Run Code Online (Sandbox Code Playgroud)
但这也失败了.
那么变量在哪里uuid_?
因为当我somePet使用Serializer 打印出当前控制台中的所有变量时,我会得到类似的东西
* cat.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;
Run Code Online (Sandbox Code Playgroud)
要么
* dog.foo = 1
* dog.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;
Run Code Online (Sandbox Code Playgroud)
在控制台中.
所以变量uuid_有一个默认值.
(我在这篇文章中使用的是序列化程序)
那么如何uuid_在我的java片段中获取变量?
首先,Serializer包装下没有这样的java.util东西,所以你正在使用别的东西.
An trait被转换为Java interface,它本身不能包含字段.
但是,您正尝试通过Pet界面访问该字段
pet.class.getField(...)
Run Code Online (Sandbox Code Playgroud)
那不行.您需要在混凝土内寻找场地class.
此外,该字段将private默认为,因为访问是通过a授予的getter.
该getField方法能够检索public整个类层次结构的每个字段(这意味着甚至是超类),同时getDeclaredField能够检索protected和private字段,但仅限于您从中调用它的确切类.你还需要打电话setAccessible(true),因为
值true表示反射对象在使用时应禁止Java语言访问检查.值false表示反射对象应强制执行Java语言访问检查
正确的代码将是(dog具体实例)
final Field uuid = dog.getClass().getDeclaredField("uuid_");
uuid.setAccessible(true);
final Object o = uuid.get(dog);
Run Code Online (Sandbox Code Playgroud)
或使用自动 getter
final Method uuid = dog.getClass().getMethod("uuid_");
final Object o = uuid_.invoke(dog);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |