在我正在处理的项目的许多类中,我看到名为CLASS_NAME的私有静态最终成员,其定义如下:
public class MyClass {
private static final String CLASS_NAME = MyClass.class.getName();
//...
}
如果有的话,获取类名有什么好处,而不是直接在需要名称的地方进行MyClass.class.getName()
调用?
答案 0 :(得分:12)
以下是Class.getName()
public String getName() {
if (name == null)
name = getName0();
return name;
}
正如您所看到的,名称的值已缓存,因此调用并不太昂贵。这就像常规吸气者的召唤一样。无论如何,如果你经常调用它,那么定义常量可能是一种很好的风格。
答案 1 :(得分:6)
缓存类名将带来另一个引用的开销。这改变了内存占用的JVM操作码(cpu复杂性)的成本。
现在CPU速度非常快,基本上等待内存,所以如果你必须在操作码和内存占用之间做出选择,最好选择通过JVM运行更多的操作码。
起初这看起来并不直观;但是,请考虑JVM和周围的硬件。较大的内存占用量意味着缓存中最近访问的项目较少,重新获取缓存中的项目的成本大约是运行单个JVM操作码的成本的1,000到10,000倍。将此与JVM的jit引擎相结合,大量访问的代码块的CPU复杂性可以免费优化(除了其他所有内容)。
因此,一般情况下,我会通过不缓存引用来修剪对象,因为它会允许更多的对象被推入1级缓存。但是,像所有现实世界的性能调整一样,您应该测试结果是否与假设相符,并以不会被JVM的所有其他内部工作混淆的方式进行测试。
答案 2 :(得分:1)
不,它根本不贵。我能想到的唯一好处是IDE可以快速显示这个特定常量的使用位置,对于长类名,常量会更短,使代码更清晰。
答案 3 :(得分:1)
这不贵。它似乎是一个用于记录目的的惯例。
比较
logger.entering(CLASS_NAME, ... )
到
logger.entering( MyClass.class.getName() ,... )
除此之外,当复制到另一个源时,日志代码不会中断(记录错误的类)。
答案 4 :(得分:0)
我们必须查看所有代码,以了解如何使用CLASS_NAME
。但是,它可能在其他地方使用,例如你可以像Log4J一样使用它:
// Log4j . Logger --- Get class name in static context by creating an anonymous Throwable and
// getting the top of its stack-trace.
// NOTE you must use: getClassName() because getClass() just returns StackTraceElement.class
static final Logger logger = Logger.getLogger(new Throwable() .getStackTrace()[0].getClassName());
这不是一项昂贵的操作,很可能会被缓存。