为另一个类命名字段

huangapple go评论62阅读模式
英文:

Named fields for another class

问题

I need to access some private fields via reflection. While this is considered bad, it is an external library and I have no other way to access it. The field names (and types) are known in advance (during compile time) and as a precaution for future library updates I want the compiler to throw an error when this field doesn't exist anymore.

Lombok has the annotation @FieldNameConstants which generates all field names as static Strings. When the field doesn't exist anymore, the static variable won't generate and the compiler will throw an error. This would be a great solution, but as this is an external library class I cannot annotate it with lombok.

英文:

I need to access some private fields via reflection. While this is considered bad, it is an external library and I have no other way to access it. The field names (and types) are known in advance (during compile time) and as a precaution for future library updates I want the compiler to throw an error when this field doesn't exist anymore.

Lombok has the annotation @FieldNameConstants which generates all field names as static Strings. When the field doesn't exist anymore, the static variable won't generate and the compiler will throw an error. This would be a great solution, but as this is an external library class I cannot annotate it with lombok.

答案1

得分: 2

如果在编译时无法失败,第二好的方法是添加一个单元测试,调用您的反射代码。这样,如果您在每次依赖更新后运行测试(无论如何都应该这样做),如果您依赖的实现细节发生更改,您的测试就会失败。

如果您绝对想要在编译时失败,您需要某种预处理器。例如,您可以构建一个小型的专用代码生成器,根据您考虑的反射生成一个桥接口,但在不能解析的字段上生成方法失败。然后只使用生成的桥接代码。我不知道有哪个库可以直接实现这一点,但在特定情况下编写它并不太难(它不需要很灵活)。

这仍然可能导致运行时问题,例如如果依赖项的编译时和运行时版本不同,或者由于某种原因未替换旧生成的代码。因此,请确保还添加单元测试。

英文:

If you cannot fail during compile time, the second best thing is to add a Unit Test that invokes your reflection code. That way, if you run your tests after every dependency update (you should do that anyway), your test will fail if the implementation details you rely on change.

If you absolutely want to fail compilation, you'll need some kind of preprocessor. You could, for example, build a small, specialized code generator that generates a bridge interface based on the reflection you have in mind, but fails to generate methods for fields it cannot resolve. Then you only use the generated bridge code. I'm not aware of a library that can do this out of the box, but it's not very hard to write in the specific case (it does not need to be flexible).

This could still lead to runtime problems, for example if the compiletime and runtime versions of your dependencies differ, or if old generated code is not replaced for some reason. So make sure to also add Unit Tests.

huangapple
  • 本文由 发表于 2023年5月11日 15:28:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76225092.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定