我正在审核具有此结构的代码。 MyClass
是类的名称。为什么有人会使用
String name = MyClass.class.getName();
而不是
String name = "MyClass";
鉴于前者已经确定了班级名称?我有什么遗失的吗?
答案 0 :(得分:7)
如果稍后重命名该类,则需要检查并修复MyClass.class.getName()
引用以进行编译(或者将由IDE自动修复)。字符串不会,这意味着它将正确编译,但实际上不能正常工作,这更糟糕,因为它隐藏了问题。
参考类名这种方式是Don't Repeat Yourself原则的应用。
答案 1 :(得分:7)
如果你不小心拼写了第一个MyClas.class.getName()
,它将无法编译。第二个会。
此外,正如JB Nizet指出的那样,getName
包含名称中的完整包层次结构。例如,如果MyClass
包含在com.piotrchernin
包下,则MyClass.class.getName()
将为"com.piotrchernin.MyClass"
,而不是"MyClass"
。
答案 2 :(得分:2)
方法getName()
:
不懂课程的代码
如您所知,获取Class对象的一种方法是MyClass.class
。但是,这不是唯一的方法。您还可以在类的对象上调用方法getClass()
- 即使在通过接口或超类类型引用对象的代码中也是如此。并且一些代码从调用者接收Class对象。
作为前者的示例,请考虑以下类层次结构和工厂方法:
public interface IFoo { }
public class AlphaFoo implements IFoo {}
public class BetaFoo implements IFoo {}
public FooFactory {
public static IFoo makeFoo() { ... }
}
工厂的来电者不知道将返回什么样的IFoo。如果您想调试打印从工厂收到的实际类,您可以这样做:
IFoo foo = FooFactory.makeFoo();
System.out.println( foo.getClass().getName() );
重构
作为重构的弹性示例,请考虑创建标准Java记录器:
public class Bar {
private static final Logger s_logger = Logger.getLogger(
Bar.class.getName() );
...
}
如果我使用IDE的重构工具重命名该类,则记录器名称将自动更新。
<强>阵列强>
您可以在表示数组的Class对象上调用getName()
。
String[] strs = new String[] { "alpha", "beta", "gamma" };
System.out.println( strs.getClass().getName() );
输出结果为:
[Ljava.lang.String;
现在,您可能会问这是如何有用的。这种语法结果是如何在调用JNI方法GetMethodID()
时表达数组参数,这是从C / C ++调用Java方法所必需的。