Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在给定类名的情况下查找包名?_Java_Class_Reflection_Package - Fatal编程技术网

Java 如何在给定类名的情况下查找包名?

Java 如何在给定类名的情况下查找包名?,java,class,reflection,package,Java,Class,Reflection,Package,给定一个类名作为字符串,如何在运行时获取它的包名?我没有包名+类名的完全限定名。只需输入类名即可 我想在Class.forName()方法中使用包名 我完全可以找到第一个匹配的包名(如果多个包具有相同的类) 有什么想法吗 更新 我没有要处理的类实例。我的要求是使用Class.forName()方法创建一个类。但我只是将类名作为字符串。我需要一些方法来循环遍历包,并确定我拥有的类是否属于包 异常的堆栈跟踪为 Exception in thread "main" java.lang.ClassNot

给定一个类名作为字符串,如何在运行时获取它的包名?我没有包名+类名的完全限定名。只需输入类名即可

我想在
Class.forName()方法中使用包名

我完全可以找到第一个匹配的包名(如果多个包具有相同的类)

有什么想法吗

更新

我没有要处理的类实例。我的要求是使用
Class.forName()
方法创建一个类。但我只是将类名作为字符串。我需要一些方法来循环遍历包,并确定我拥有的类是否属于包

异常的堆栈跟踪为

Exception in thread "main" java.lang.ClassNotFoundException: MyAddressBookPage
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)

唯一的方法是在类路径和具有类名的条目中导航目录/JAR

这里有一些代码几乎可以满足您的需要。这段代码是我拥有的一个类的一部分,该类搜索用于创建接口实例的实现/工厂方法。很抱歉,没有时间更改此项以查找命名类,这应该是一个简单的更改,正如我在其他地方提到的,您不需要加载该类,只需检查名称即可

public Class<?> locateImplementation(Class<?> type) {
     Class<?> c = null;
     String[] cp = System.getProperty("java.class.path").split(File.pathSeparator);

     for (int i = 0; (c == null) && (i < cp.length); ++i) {
         File f = new File(cp[i]);
         if (f.exists() && f.canRead()) {
             if (isJar(f)) {
                 try {
                     c = searchJar(type, new FileInputStream(f));
                 } catch (Throwable t) {
                     // Nothing to worry about
                 }
             } else {
                 c = searchFile(type, f);
             }
         }
     }

     return c;
 }

private boolean isClass(String path) {
    return path.matches(".+\\.class$") && !path.contains("$");
}

private Class<?> searchFile(Class<?> type, File f) {
    return searchFile(type, f, f.getPath());
}

private Class<?> searchFile(Class<?> type, File f, String root) {
    Class<?> implementation = null;

    if (f.isDirectory()) {
        File[] files = f.listFiles();
        for (int i = 0; i < files.length; i++) {
            implementation = searchFile(type, files[i], root);
            if (implementation != null) {
                break;
            }
        }
    } else if (isClass(f.getPath())) {
        String path = f.getPath().substring(root.length() + 1);
        Class<?> c = getClass(path);
        if ((c != null) && !c.isInterface() &&
                type.isAssignableFrom(c)) {
            implementation = c;
        }
    }
    return implementation;
}

private Class<?> getClass(String name) {
    Class<?> c;
    String className = name.replaceAll("[/\\\\]", ".")
        .replaceFirst("^\\.", "").replace(".class", "");
    try {
        c = Class.forName(className);
    } catch (Throwable e) {
        c = null;
    }

    return c;
}


private Class<?> searchJar(Class<?> type, InputStream in)
        throws Exception {
    ZipInputStream zin = new ZipInputStream(in);
    Class<?> implementation = null;

    ZipEntry ze;
    while ((implementation == null)
            && ((ze = zin.getNextEntry()) != null)) {
        String name = ze.getName();
        if (name.endsWith("class")
                && name.matches("^com.xxx.+")
                && !name.contains("$")) {
            try {
                Class<?> c = getClass(name);
                if ((c != null) && !c.isInterface()
                        && type.isAssignableFrom(c)) {
                    implementation = c;
                }
            } catch (Throwable t) {
                // Nothing to worry about
            }
        }
    }

    return implementation;
}

private boolean isJar(File f) {
    return f.getPath().endsWith(".jar");
}
公共类locateImplementation(类类型){
c类=空;
String[]cp=System.getProperty(“java.class.path”).split(File.pathSeparator);
对于(int i=0;(c==null)和(i
这很可能是一种效率极低、臃肿、不方便的方式来完成您试图实现的目标,希望已经有一种开箱即用的单一方式来实现。。。但它应该起作用

基本上,扫描类路径中的每个类,直到找到一个
getSimpleName()
与您拥有的类名匹配的类

我建议查看以帮助管理这样做的具体细节

它可能看起来像这样:

 ClassPath classpath = new ClassPathFactory().createFromJVM();
 RegExpResourceFilter regExpResourceFilter = new RegExpResourceFilter(".*", ".*\\.class");
 String[] resources = classpath.findResources("", regExpResourceFilter);
resources
是一个字符串数组,如“com/foo/bar/Baz.class”。您现在可以简单地循环查找匹配的条目,并将它们从斜线转换为虚线,去掉“.class”等。在尝试匹配内部类时要小心,因为它们将包含“$”字符


另外,据我所知,这将不会导致加载这些类

最简单的解决方案之一:

 final Package[] packages = Package.getPackages();
    final String className = "ArrayList";

    for (final Package p : packages) {
        final String pack = p.getName();
        final String tentative = pack + "." + className;
        try {
            Class.forName(tentative);
        } catch (final ClassNotFoundException e) {
            continue;
        }
        System.out.println(pack);
        break;
    }
Test.class.toString().replace("class", "").replace(".","/").replace(" ", "")

对该类调用getPackageName()。它返回完全限定的包名。另外,值得一提的是,这是Java 9的一项功能。

您不需要class.forName的类实例来工作。阅读我回答中的评论为什么你要投票否决所有人?我们只是想帮忙。如果每个人都给出了相似的答案,那么这就意味着你不能很好地描述你的问题,这首先是你的错。举例说明你在类名和完全限定类名方面的意思可能有助于消除混淆,例如。“我只有‘Baz’,没有‘com.foo.bar.Baz’。@Cemre,不是他,是我。我投票反对他们,因为他们没有回答他的问题。不要把它当成个人的!:)一旦它们被编辑成有用的答案,我将返回并删除不再适用的否决票。但目前,这些都不是很好的答案。这就是我们如何开始从没有答案到网络上最好答案的旅程。再说一次,不要把它当成个人的事。很抱歉误解了。看到我已经很低的声誉下降有点吓人@Grundlefleck感谢您的回复