通过反射获取 Java 字段,而不是通过其 String 名称
如果我有字段本身,是否可以通过Java反射获取字段?这是一个原始的浮动(公共,没问题)。我不想将其名称用作字符串。
示例:
public class TVset {
public float voltageA;
public float voltageB;
public float voltageC;
public TVset(...) {...} // constructor
public void function() {...} // it changes voltages
}
class Voltmeter{
Object theObject;
Field theField;
Voltmeter(Object obj) {
theObject = obj;
Class theFieldClass = obj.getClass();
Class theContainerClass = theFieldClass.getDeclaringClass();
Field theField = ??? // <-- here I don't want to use a String
}
float getVoltage() {
return theField.getFloat(theObject);
}
}
TVset tv1 = new TVset(...);
TVset tv2 = new TVset(...);
Voltmeter meter = new Voltmeter(tv1.voltageB);
meter.getVoltage();
tv1.function();
meter.getVoltage(); <- should reflect the changed voltage
tv1.function();
meter.getVoltage(); <- should reflect the changed voltage
...
效果类似于通过引用传递浮点数,但不将其包装到包装类中。
我需要测量不同电视机上的不同电压,只需将行:更改
Voltmeter meter = new Voltmeter(tv1.voltageB);
为其他内容,例如:
Voltmeter meter = new Voltmeter(tv2.voltageA);
是否可以通过反射来做到这一点?
谢谢
Is it possible to get a Field through Java reflection if I have the field itself? It's a primitive float (public, no problem). I don't want to use its name as a String.
Example:
public class TVset {
public float voltageA;
public float voltageB;
public float voltageC;
public TVset(...) {...} // constructor
public void function() {...} // it changes voltages
}
class Voltmeter{
Object theObject;
Field theField;
Voltmeter(Object obj) {
theObject = obj;
Class theFieldClass = obj.getClass();
Class theContainerClass = theFieldClass.getDeclaringClass();
Field theField = ??? // <-- here I don't want to use a String
}
float getVoltage() {
return theField.getFloat(theObject);
}
}
TVset tv1 = new TVset(...);
TVset tv2 = new TVset(...);
Voltmeter meter = new Voltmeter(tv1.voltageB);
meter.getVoltage();
tv1.function();
meter.getVoltage(); <- should reflect the changed voltage
tv1.function();
meter.getVoltage(); <- should reflect the changed voltage
...
The effect is similar to passing the float by reference, but without wrapping it into a wrapper class.
I need to measure different voltages on different TV sets, just by changing the line:
Voltmeter meter = new Voltmeter(tv1.voltageB);
to something else, like:
Voltmeter meter = new Voltmeter(tv2.voltageA);
Is it possible to do it with reflection?
Thx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
要使用反射,您必须使用字符串。您可以使用对象来包装可变浮点或简单的浮点[1],而不是使用浮点;
顺便说一句,除非你有充分的理由,否则我不会使用 float,double 的舍入误差要小得多。
编辑:使用抽象访问器。这是最快的方法。 AFAIK,差异小于 10 纳秒。
就我个人而言,如果速度至关重要,我会直接按名称使用字段。没有比这更简单或更快的了。
To use reflection you have to use a String. Instead of using a float you can use an object to wrap mutable float or a simple float[1];
BTW I wouldn't use float unless you have a really good reason, double suffers far less rounding error.
EDIT: Using an abstract accessor. This is the fastest way to do this. AFAIK,the difference is less than 10 nano-seconds.
Personally, if speed is critical, I would just use the fields directly by name. You won't get simpler or faster than that.
为了完整起见,我添加了解决此问题的委托方法。我也不建议让您的花车可供公众使用。
Just for completeness I've included the delegate way of solving this. I would also not recommend having your floats with public access.
如果您控制 TVSet 但由于某种原因需要使用反射,避免错误的一个好方法是将您需要的方法/字段名称编写为 TVSet 类中的字符串常量。
但是,如果您关心的是性能,那么反射就不是最佳选择,因为通过反射访问字段或方法可能比通过 getter 或直接访问慢得多。
If you control the TVSet but need to use reflection for some reason, a good way to avoid errors is to write the method/field names that you need as String Constants in the TVSet class.
However if your concern is performance, reflection is not the way to go because accessing a field or method through reflection can be much slower than accessing through getters or directly.
这是一个变体,您可以在其中提供
float
值而不是字符串。然后这样调用它:
仅当电压表创建时的电压不同(而不是 NaN)时它才起作用,因为它采用具有正确值的第一个字段。我认为这并没有真正提高效率。
我真的不会推荐这个。
Here a variant where you can give your
float
value instead of a string.Then call it like this:
It works only if the voltages in the moment of Voltmeter creation are different (and not NaN), as it takes the first Field with the right value. And it is not really more efficient, I think.
I wouldn't really recommend this.