我知道这个帖子很旧,但它是谷歌搜索的最高结果,对我来说,这里没有令人满意的答案。这是我写的一些代码,对我很有用。当然,需要注意的是它可能没有从磁盘加载,但它解释了这一点,并在这种情况下返回 null。这适用于查找“容器”,即类的根位置,无论是 jar 还是文件夹。这可能不直接满足您的需求。如果没有,请随意删除您确实需要的代码部分。
/**
* Returns the container url for this class. This varies based on whether or
* not the class files are in a zip/jar or not, so this method standardizes
* that. The method may return null, if the class is a dynamically generated
* class (perhaps with asm, or a proxy class)
*
* @param c The class to find the container for
* @return
*/
public static String GetClassContainer(Class c) {
if (c == null) {
throw new NullPointerException("The Class passed to this method may not be null");
}
try {
while(c.isMemberClass() || c.isAnonymousClass()){
c = c.getEnclosingClass(); //Get the actual enclosing file
}
if (c.getProtectionDomain().getCodeSource() == null) {
//This is a proxy or other dynamically generated class, and has no physical container,
//so just return null.
return null;
}
String packageRoot;
try {
//This is the full path to THIS file, but we need to get the package root.
String thisClass = c.getResource(c.getSimpleName() + ".class").toString();
packageRoot = StringUtils.replaceLast(thisClass, Pattern.quote(c.getName().replaceAll("\\.", "/") + ".class"), "");
if(packageRoot.endsWith("!/")){
packageRoot = StringUtils.replaceLast(packageRoot, "!/", "");
}
} catch (Exception e) {
//Hmm, ok, try this then
packageRoot = c.getProtectionDomain().getCodeSource().getLocation().toString();
}
packageRoot = URLDecoder.decode(packageRoot, "UTF-8");
return packageRoot;
} catch (Exception e) {
throw new RuntimeException("While interrogating " + c.getName() + ", an unexpected exception was thrown.", e);
}
}