0

在java反射中,我们一般会尝试在运行时通过属性名来获取字段值。但考虑到性能影响,不建议使用反射。

但是在这种情况下,我们可以使用 groovy 对象,它允许通过属性名称检索值

例如:

Person.groovy

Class Person { String name }

主应用程序.java

Class MainApp { 
       public static void main(String[] args) { 
             Person p = new Person(); 
             p."name"="jonh";
       }
}

这将具有与反射相同的性能吗?

4

1 回答 1

2

许多动态 groovy 功能​​将使用反射或类似的东西,导致性能低于静态编译的代码。在某些情况下,Groovy 代码甚至可能使用内部抛出和捕获的异常。来自Cédric Champeau 的博客

[...] 有人在 Groovy 中做出了糟糕的设计决定。[...] 这个想法是依靠异常来控制属性解析的流程。这意味着当一个属性丢失时,通常在闭包中,会引发异常。当找不到方法时,将引发异常。当未找到属性时,将引发异常。这似乎是个好主意,因为最终,您希望向用户提供错误,但在实践中,这是灾难性的,因为 Groovy 可以捕获这些异常。[...] 这对性能产生了可怕的影响。[...] 因此,如果您在 Groovy 中编写插件,为了性能起见,请添加 @CompileStatic。

但是通过使用 Groovy,您已经在很多地方接受了这种性能影响,因此这个问题似乎毫无意义。如果您担心这种微观性能问题,Groovy 通常是错误的语言。

请注意,通过@CompileStatic在所有类上使用,您可能可以避免您自己的代码出现这种性能问题(但是动态特性不会编译/行为不同),但对于任何 groovy SDK 或 groovy 库类仍然可能是这种情况你依赖。

关于字段访问

在您的示例中,如果您使用常量字符串,编译器可能会将其优化为p.name.

是否这样做可能取决于 Groovy 版本(未来版本的处理方式可能与当前版本不同)。

于 2018-01-09T01:23:29.610 回答