在java反射中,我们通常尝试通过属性名称在运行时获取字段值。但考虑到性能影响,不建议使用反射。
但在这种情况下,我们可以使用 groovy 对象,它允许通过属性名称检索值
例如:
Person.groovy
Class Person { String name }
MainApp.java
Class MainApp {
public static void main(String[] args) {
Person p = new Person();
p."name"="jonh";
}
}
这会具有与反射相同的性能吗?
最佳答案
许多动态 Groovy 功能将使用反射或类似的东西,导致性能低于静态编译的代码。在某些情况下,Groovy 代码甚至可能使用内部引发和捕获的异常。来自 Cédric Champeau's blog :
[...] someone made a terrible design decision in Groovy. [...] the idea was to rely on exceptions to control the flow of resolution of properties. This means that when a property is missing, typically in a closure, an exception is thrown. When a method is not found, an exception is thrown. When a property is not found, an exception is thrown. That seemed to be a good idea, because in the end, you want to provide the user with an error, but in practice, this is catastrophic, because Groovy can capture those exceptions. [...] And that has a terrible impact on performance. [...] So, if you’re writing a plugin in Groovy, for the sake of performance, please add @CompileStatic.
但是通过使用 Groovy,您已经在很多地方接受了这种性能影响,因此这个问题似乎毫无意义。如果您担心这种微观性能问题,Groovy 通常是错误的语言。
请注意,通过在所有类上使用 @CompileStatic
,您可能可以避免自己的代码出现此类性能问题(但是动态功能不会编译/表现不同),但它可以对于您所依赖的任何 groovy SDK 或 groovy 库类来说,情况仍然如此。
关于字段访问
在您的示例中,如果您使用常量字符串,编译器可能会将其优化为 p.name
。
是否可能取决于 Groovy 版本( future 版本的处理方式可能与当前版本不同)。
关于java - 使用 groovy 对象而不是使用 java 反射是一个好的选择吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47214487/