JAVA字节码优化

Ido*_*ash 1 java performance

这是一个基本问题.

我的代码不应该在元数据bean上运行.所有元数据bean都位于元数据包下.

现在,

我使用反射API来确定一个类是否位于元数据包中.

if (newEntity.getClass().getPackage().getName().contains("metadata")) 
Run Code Online (Sandbox Code Playgroud)

我在这段代码中的几个地方使用了这个.

问题是:我应该这样做一次:

boolean isMetadata = false
if (newEntity.getClass().getPackage().getName().contains("metadata")) {
   isMetadata = true;
}
Run Code Online (Sandbox Code Playgroud)

C++进行优化,并知道此代码已被调用,并且不会再次调用它.JAVA会进行优化吗?我知道反射API很重,我不想丢失昂贵的运行时间.

DNA*_*DNA 6

当然,在将任何工作进行优化之前,您应该检查是否确实存在性能问题.getClass()可能已经非常快(instanceof无论如何都要快).您可以缓存元数据包中的类集,这样您就不需要继续检查包名.

如果您确实需要比较包,可以使用Package.getPackage(String name)方法找到元数据包一次,然后对每个对象,getClass().getPackage()像以前一样调用,并比较两个包对象.

这比检查包名中的字符串更快更优雅,但如果有多个类加载器可能无法正常工作,因为Package对象不相等(==)且Package不会覆盖.equals().考虑到它,它甚至可能无法保证在单个类加载器上工作,但我怀疑在实践中你得到的是相同的Package实例而不是另一个副本 - 最好先检查一下!例如:

String.class.getPackage() == Integer.class.getPackage() // should be true
Run Code Online (Sandbox Code Playgroud)

更新,如果你检查源代码Class.getPackage(),Package.getPackage()而且ClassLoader.getPackage()你可以看到他们缓存Package的对象,因此使用单一类加载器时,你应该是安全的比较它们

程序包命名约定的一个问题是您必须在整个代码库中强制执行和维护它,这可能会随着时间的推移而成为维护问题.更明确的识别类的方法可能更好.

识别特定类别组的替代方法包括:

  • 使您的元数据bean实现标记接口
  • 使用Java Annotations标记元数据bean
  • 使所有 bean实现一个通用接口,该接口可以调用以检查是否属于您定义的特定类别.这是丑陋的,因为它基本上复制了类型系统,但由于它不需要反射,因此速度很快.