1

这是一个基本问题。

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

现在,

我使用反射 API 来找出一个类是否位于元数据包中。

if (newEntity.getClass().getPackage().getName().contains("metadata")) 

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

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

boolean isMetadata = false
if (newEntity.getClass().getPackage().getName().contains("metadata")) {
   isMetadata = true;
}

C++ 进行优化并且知道该代码已经被调用并且它不会再次调用它。JAVA会做优化吗?我知道反射 API 是一个沉重的节拍,我不想失去昂贵的运行时。

4

1 回答 1

6

您当然应该在进行任何优化之前检查是否真的存在性能问题。getClass()可能已经相当快了(instanceof无论如何都比 快)。您可能会缓存元数据包中的一组类,因此您无需继续检查包名称。

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

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

String.class.getPackage() == Integer.class.getPackage() // should be true

如果您检查源代码进行更新Class.getPackage(),您可以看到它们缓存了对象Package.getPackage(),因此在使用单个类加载器时应该安全地比较它们ClassLoader.getPackage()Package

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

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

  • 使您的元数据 bean 实现标记接口
  • 使用 Java Annotations 标记元数据 bean
  • 使所有bean 实现一个公共接口,该接口可以调用一个方法来检查它们是否属于您定义的特定类别。这很难看,因为它基本上是在复制类型系统,但会很快,因为它不需要反射。
于 2012-11-25T10:44:37.957 回答