Java 如何获取 .class 文件的包名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20925024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 05:21:55  来源:igfitidea点击:

How to get a package name of .class file?

javaclassreflectionruntimepackage

提问by Wicia

I have an unusual problem which is concerned to dynamic loading java .class file at run-time. All I want to do is to load a .class file and basing on it create a Class object.

我有一个不寻常的问题,它与在运行时动态加载 java .class 文件有关。我想要做的就是加载一个 .class 文件并基于它创建一个 Class 对象。

Input: an absolute path of .class file.

输入:.class文件的绝对路径。

Basing on it i want to load class by ClassLoader, so I need a path of root directory where file is located and full class name e.g com.test.MyClass. Basing on mentioned absolute path I can only get a class name but I can't get a package name which is "hiden" in this file.

基于它,我想通过 ClassLoader 加载类,所以我需要文件所在的根目录路径和完整的类名,例如 com.test.MyClass。基于提到的绝对路径,我只能获得一个类名,但我无法获得在此文件中“隐藏”的包名。

Here is code of my "loading class method":

这是我的“加载类方法”的代码:

    public static void loadClass(String directory){

        // Get file root directory
        String rootDirectory = new File(directory).getParent();

        // Get rid of file extension
        String className = getFileNameWithoutExtension(directory);

        URL[] urls = null;
        ClassLoader cl = null;

        try {
            // Convert File to a URL and save them
            urls = new URL[]{new File(rootDirectory).toURI().toURL()};

            // Create a new class loader with the directory
            cl = new URLClassLoader(urls);

            // Load in the class
            dynamicClass = cl.loadClass(className);
        } 
        catch (MalformedURLException e) 
        {

    } 
    catch (ClassNotFoundException e) 
    {

    }
    catch (NoClassDefFoundError e)
    {
        // Basing on error message get the class package name
        String classPackage = getClassPackage(e.getMessage());

        try {             

           // Load the class once more!
           dynamicClass = cl.loadClass(classPackage);
        } 
        catch (ClassNotFoundException ex) 
        {

        }
    }
}

Second method is used to get package name from exception message:

第二种方法用于从异常消息中获取包名:

private static String getClassPackage(String errorMsg){

    // Start and end index of cutting
    int startIndex = errorMsg.lastIndexOf(" ") + 1;
    int endIndex = errorMsg.length() - 1;

    // Let's save a substring
    String classPackage = errorMsg.substring(startIndex, endIndex);

    // Replace char '/' to '.'
    classPackage = classPackage.replace('/', '.');

    return classPackage;
}

Code of method getFileNameWithoutExtension:

方法getFileNameWithoutExtension 的代码:

private static String getFileNameWithoutExtension(String path){
    int start = path.lastIndexOf(File.separator) + 1;
    int end = path.lastIndexOf(DOT);
    end = start < end ? end : path.length();
    String name = path.substring(start, end);

    return name;
}

Where the static final variable is:

其中静态最终变量是:

private static final String DOT = ".";

And here is my question: is it possible to get package name from .class file without using this kind of trick?

这是我的问题:是否可以在不使用这种技巧的情况下从 .class 文件中获取包名?

回答by William Reed

You can use the Foo.class.getPackage().getName()method to determine this.

您可以使用该Foo.class.getPackage().getName()方法来确定这一点。

    public Package getPackage()

Returns:

返回:

the package of the class, or null if no package information is available from the archive or codebase.

类的包,如果存档或代码库中没有可用的包信息,则为 null。

Using getName() :

使用 getName() :

    public String getName()

Returns:

返回:

The fully-qualified name of this package as defined in section 6.5.3 of The Java? Language Specification, for example, java.lang

The Java 的 6.5.3 节中定义的此包的完全限定名称?语言规范,例如java.lang

回答by ADTC

Since you already have the required data in className, just use it again. You don't need the getClassPackagemethod.

由于您已经在 中拥有所需的数据className,只需再次使用它即可。你不需要这个getClassPackage方法。

    catch (NoClassDefFoundError e)
    {
        // Basing on error message get the class package name
        //But we already have the class name in className variable!
        //String classPackage = getClassPackage(e.getMessage());

        try {             

           // Load the class once more!
           dynamicClass = cl.loadClass(className);
        } 
        catch (ClassNotFoundException ex) 
        {

        }
    }

And if you want to get the package name only (not sure why), you can just get it from the class name:

如果你只想获取包名(不知道为什么),你可以从类名中获取它:

String packageName = className.substring(0, className.lastIndexOf('.'));
dynamicClass = cl.loadClass(packageName);

回答by Akhilesh Dhar Dubey

You can do like this-

你可以这样做-

String packName = new Object(){}.getClass().getPackage().getName();        
System.out.println(packName);