代码之家  ›  专栏  ›  技术社区  ›  luke

查找从何处加载java类

  •  163
  • luke  · 技术社区  · 16 年前

    problem 类加载器加载的类版本不正确,因为它位于两个不同位置的类路径上。

    那么,如何让类加载器告诉我实际的类文件来自磁盘上的什么地方呢?

    如果类加载器由于版本不匹配(或其他原因)而无法加载该类,我们是否可以在它读取之前找出它试图读取的文件?

    10 回复  |  直到 7 年前
        1
  •  200
  •   Jon Skeet    16 年前

    下面是一个例子:

    package foo;
    
    public class Test
    {
        public static void main(String[] args)
        {
            ClassLoader loader = Test.class.getClassLoader();
            System.out.println(loader.getResource("foo/Test.class"));
        }
    }
    

    这张照片打印出来:

    file:/C:/Users/Jon/Test/foo/Test.class
    
        2
  •  105
  •   Ajinkya Amit Jain    8 年前

    -verbose:class

        3
  •  88
  •   Saurabh Gokhale    14 年前
    getClass().getProtectionDomain().getCodeSource().getLocation();
    
        4
  •  28
  •   David Dossot    12 年前

    这就是我们所使用的:

    public static String getClassResource(Class<?> klass) {
      return klass.getClassLoader().getResource(
         klass.getName().replace('.', '/') + ".class").toString();
    }
    

    这取决于类加载器实现: getClass().getProtectionDomain().getCodeSource().getLocation()

        5
  •  20
  •   OldCurmudgeon    11 年前

    当对象被删除时,Jon的版本失败 ClassLoader null 类装载器 .

    此方法处理该问题:

    public static String whereFrom(Object o) {
      if ( o == null ) {
        return null;
      }
      Class<?> c = o.getClass();
      ClassLoader loader = c.getClassLoader();
      if ( loader == null ) {
        // Try the bootstrap classloader - obtained from the ultimate parent of the System Class Loader.
        loader = ClassLoader.getSystemClassLoader();
        while ( loader != null && loader.getParent() != null ) {
          loader = loader.getParent();
        }
      }
      if (loader != null) {
        String name = c.getCanonicalName();
        URL resource = loader.getResource(name.replace(".", "/") + ".class");
        if ( resource != null ) {
          return resource.toString();
        }
      }
      return "Unknown";
    }
    
        6
  •  5
  •   ecerer    9 年前

    Main

    Class<?> c = Main.class;
    String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", "");
    
    System.out.println(path);
    

    输出:

    /C:/Users/Test/bin/
    

    也许是糟糕的风格,但很好!

        7
  •  3
  •   Hongyang    7 年前

    通常,我们不知道如何使用硬编码。我们可以先获取className,然后使用ClassLoader获取类URL。

            String className = MyClass.class.getName().replace(".", "/")+".class";
            URL classUrl  = MyClass.class.getClassLoader().getResource(className);
            String fullPath = classUrl==null ? null : classUrl.getPath();
    
        8
  •  1
  •   Community CDub    8 年前

    看看这个类似的问题。 Tool to discover same class..

    我认为最相关的障碍是您是否有一个自定义类加载器(从db或ldap加载)

        9
  •  1
  •   seduardo    5 年前

    简单方法:

    System.out.println(java.lang.String.class.getResource(String.class.getSimpleName()+“.class”);

    jar:file:/D:/Java/jdk1.8/jre/lib/rt.jar/java/lang/String.class

    String obj=“简单测试”; System.out.println(obj.getClass().getResource(obj.getClass().getSimpleName()+“.class”);

    例如:

        10
  •  0
  •   Adam    8 年前

    此方法适用于文件和JAR:

    Class clazz = Class.forName(nameOfClassYouWant);
    
    URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
    InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish
    
        11
  •  -1
  •   Daniel Spiewak    16 年前

    假设您使用的是一个名为 MyClass ,以下各项应能发挥作用:

    MyClass.class.getClassLoader();
    

    能否获取.class文件的磁盘位置取决于类加载器本身。例如,如果您使用类似BCEL的东西,某个类甚至可能没有磁盘上的表示形式。