Answers:
只需使用TheClassName.class
代替即可getClass()
。
由于这在特定用例上引起了极大的关注-提供了一种简单的方法来插入日志声明-我想我会对此加点子。日志框架通常期望将日志限制在特定的上下文中,例如完全限定的类名。因此,它们未经修改就不能复制粘贴。其他答案中提供了关于粘贴安全日志声明的建议,但它们有一些缺点,例如,字节码膨胀或添加运行时自省。我不推荐这些。复制粘贴是编辑器的考虑因素,因此最适合使用编辑器解决方案。
在IntelliJ中,我建议添加实时模板:
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
作为模板的文本。className()
现在,如果您键入,log<tab>
它将自动扩展到
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
并自动为您重新格式化和优化导入。
Log
在Android中使用,这需要提供一个标签,通常是类名。并且可能还有其他示例。当然,您可以为此声明一个字段(这是通常的做法),但是仍然可以复制粘贴。
CLASS
键入className()
。这将确保$ CLASS $实际上被类名替换,否则它将变成空。
对于问题中的代码示例,标准解决方案是通过其名称显式引用该类,甚至可以不getClassLoader()
调用而进行操作:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
这种方法还有一个缺点,那就是如果您需要将此代码复制到许多类似的类中,则对于复制/粘贴错误并不是很安全。
至于标题中的确切问题,在相邻线程中有一个技巧:
Class currentClass = new Object() { }.getClass().getEnclosingClass();
它使用嵌套的匿名Object
子类来获取执行上下文。此技巧的好处是可以安全复制/粘贴...
在其他类继承的基类中使用该类时的警告:
还值得注意的是,如果此代码段的形状是某个基类的静态方法,则currentClass
值将始终是对该基类的引用,而不是对可能正在使用该方法的任何子类的引用。
在Java7 +中,您可以在静态方法/字段中执行此操作:
MethodHandles.lookup().lookupClass()
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
我自己为此搏斗。一个不错的技巧是在静态上下文中使用当前线程获取ClassLoader。这也将在Hadoop MapReduce中工作。其他方法在本地运行时可以工作,但在MapReduce中使用时返回null InputStream。
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
getClass()
方法是在Object类中定义的,具有以下签名:
公共最终课程getClass()
由于未定义为static
,因此无法在静态代码块内调用它。有关更多信息,请参见以下答案:Q1,Q2,Q3。
如果您处于静态上下文中,则必须使用类文字表达式来获取Class,因此基本上必须这样做:
Foo类
这种类型的表达式称为类文字,在Java语言规范书中对它们进行了如下解释:
类文字是由类,接口,数组或原始类型的名称后跟“。”组成的表达式。和令牌类。类文字的类型是Class。它根据当前实例的类的定义类加载器所定义的命名类型(或为void)对Class对象求值。
您还可以在Class的API文档中找到有关此主题的信息。
尝试一下
Thread.currentThread().getStackTrace()[1].getClassName()
要么
Thread.currentThread().getStackTrace()[2].getClassName()
[1]
将导致所有日志消息Thread
作为其在Android 4.4.4上的来源报告。[2]
在Android和OpenJRE上似乎都能给出正确的结果。
假设有一个Utility类,那么示例代码将是-
URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));
CustomLocation-如果资源中有任何文件夹结构,则删除此字符串文字。
尝试这样的事情。这个对我有用。Logg(类名)
String level= "";
Properties prop = new Properties();
InputStream in =
Logg.class.getResourceAsStream("resources\\config");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
level = prop.getProperty("Level");
getResource()
在存在用户定义的实例(例如非J2SE)类的实例之前使用有时会失败。问题在于,在此阶段,JRE将使用引导类加载器,而引导类加载器的类路径上将没有应用程序资源。