使用groovy对象而不是使用java反射是不错的选择

时间:2017-11-10 01:51:33

标签: java performance groovy reflection jvm-bytecode

在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";
       }
}

这与反射有相同的表现吗?

1 个答案:

答案 0 :(得分:1)

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

  [...]有人在Groovy做出了糟糕的设计决定。 [...]   想法是依靠异常来控制分辨率的流动   属性。这意味着当一个属性丢失时,通常在一个   关闭,抛出异常。当找不到方法时,   抛出异常。找不到属性时,会出现例外情况   抛出。这似乎是一个好主意,因为最终,你想要   为用户提供错误,但在实践中,这是灾难性的,   因为Groovy可以捕获这些异常。 [...]那太可怕了   对绩效的影响。 [...]所以,如果你在Groovy中编写一个插件,那么   为了表现,请添加@CompileStatic。

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

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

关于现场访问

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

是否可能取决于Groovy版本(未来版本可能会处理与当前版本不同的版本)。