Java NoClassDefFoundError和ClassNotFoundException之间的原因和区别是什么?

Java NoClassDefFoundError和ClassNotFoundException之间的原因和区别是什么?,java,classpath,noclassdeffounderror,classnotfoundexception,Java,Classpath,Noclassdeffounderror,Classnotfoundexception,NoClassDefFoundError和ClassNotFoundException之间有什么区别 是什么原因导致它们被抛出?如何解决这些问题 在修改现有代码以包含新的jar文件时,我经常会遇到这些问题。 对于通过webstart分发的java应用程序,我在客户端和服务器端都找到了它们 我遇到的可能原因: 代码客户端的build.xml中未包含的包 我们正在使用的新JAR缺少运行时类路径 版本与以前的jar冲突 当我今天遇到这些问题时,我会采取循序渐进的方法来解决问题。我需要更加清晰和理解。N

NoClassDefFoundError
ClassNotFoundException
之间有什么区别

是什么原因导致它们被抛出?如何解决这些问题

在修改现有代码以包含新的jar文件时,我经常会遇到这些问题。 对于通过webstart分发的java应用程序,我在客户端和服务器端都找到了它们

我遇到的可能原因:

  • 代码客户端的
    build.xml
    中未包含的包
  • 我们正在使用的新JAR缺少运行时类路径
  • 版本与以前的jar冲突

  • 当我今天遇到这些问题时,我会采取循序渐进的方法来解决问题。我需要更加清晰和理解。

    NoClassDefFoundError
    基本上是一个链接错误。它发生在您尝试实例化一个对象时(静态地使用“new”),而在编译期间找不到它


    ClassNotFoundException
    更一般,当您尝试使用不存在的类时,它是一个运行时异常。例如,在接受接口的函数中有一个参数,有人传入实现该接口的类,但您无权访问该类。它还涵盖了动态类加载的情况,例如使用
    loadClass()
    class.forName()

    与Java API规范的区别如下

    用于:

    当应用程序试图 通过类的字符串加载类 名称使用:

    • class
      中的
      forName
      方法
    • ClassLoader
      中的
      findSystemClass
      方法
    • ClassLoader
      中的
      loadClass
      方法
    但对于具有 无法找到指定的名称

    用于:

    如果Java虚拟机或
    ClassLoader
    实例试图加载 在类的定义中(作为一部分) 属于普通方法调用或作为 使用新实例创建新实例 表达式),并且没有对 可以找到类

    已搜索类定义 当前正在执行时存在 类已编译,但定义 再也找不到了


    因此,
    NoClassDefFoundError
    似乎是在成功编译源代码时发生的,但在运行时,找不到所需的
    class
    文件。这可能发生在JAR文件的分发或生产过程中,其中没有包括所有必需的
    class
    文件

    至于
    ClassNotFoundException
    ,它可能源于试图在运行时对类进行反射调用,但程序试图调用的类不存在


    两者之间的区别在于一个是
    错误
    ,另一个是
    异常
    。With
    NoClassDefFoundError
    是一个
    错误
    ,它源于Java虚拟机在查找预期要查找的类时遇到问题。由于找不到
    文件,或者与编译时生成或遇到的文件不同,因此预期在编译时工作的程序无法运行。这是一个非常严重的错误,因为JVM无法启动程序

    另一方面,
    ClassNotFoundException
    是一个
    异常
    ,因此它在某种程度上是预期的,并且是可恢复的。使用反射很容易出错(由于存在一些预期,事情可能不会按预期进行。没有编译时检查以查看所有必需的类是否存在,因此在运行时会出现查找所需类的任何问题。

    当尝试通过字符串引用类来加载该类时会抛出。例如,参数to in class.forName()是一个字符串,这可能会导致传递给类加载器的二进制名称无效

    当遇到可能无效的二进制名称时,会引发ClassNotFoundException;例如,如果类名具有“/”字符,则一定会获得ClassNotFoundException。当直接引用的类在类路径上不可用时,也会引发ClassNotFoundException

        public class MainClass
        {
            public static void main(String[] args)
            {
                try
                {
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                }catch (ClassNotFoundException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
    
    
        java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at pack1.MainClass.main(MainClass.java:17)
    
    另一方面,它被抛出

    • 当类的实际物理表示形式.class文件不可用时
    • 或者该类已经加载到另一个类加载器中(通常父类加载器会加载该类,因此不能再次加载该类)
    • 或者,如果发现不兼容的类定义-类文件中的名称与请求的名称不匹配
    • 或者(最重要的)如果无法定位和加载依赖类。在这种情况下,直接引用的类可能已定位和加载,但依赖类不可用或无法加载。这是一种可以通过class.forName或等效方法加载直接引用的类的情况。这表示链接失败
    简而言之,当类加载器无法找到或加载类定义时,通常会在加载以前不存在的类的new()语句或方法调用上抛出NoClassDefFoundError(与基于字符串加载ClassNotFoundException的类相反)

    最终,当ClassLoader实现无法加载类时,它会抛出ClassNotFoundException实例。大多数自定义ClassLoader实现都会执行此操作,因为它们扩展了URLClassLoader。通常ClassLoader不会在任何方法实现上显式抛出NoClassDefFoundError-此异常on通常由热点编译器中的JVM抛出,而不是由类加载器抛出
    private static SomeClass foo = new SomeClass();
    
    class a { static class b {} public static void main(String args[]) { System.out.println("First attempt new b():"); try {new b(); } catch(Throwable t) {t.printStackTrace();} System.out.println("\nSecond attempt new b():"); try {new b(); } catch(Throwable t) {t.printStackTrace();} } } First attempt new b(): java.lang.NoClassDefFoundError: a$b at a.main(a.java:5) Caused by: java.lang.ClassNotFoundException: a$b at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) ... 1 more Second attempt new b(): java.lang.NoClassDefFoundError: a$b at a.main(a.java:7)
    public class Test1
    {
    }
    
    
    public class Test 
    {
       public static void main(String[] args)
       {
            Test1 = new Test1();    
       }
    
    }
    
    Exception in thread "main" java.lang.NoClassDefFoundError: Test
        at Test1.main(Test1.java:5)
    Caused by: java.lang.ClassNotFoundException: Test
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more
    
    class A{
     void met(){
       Class.forName("com.example.Class1");
     }
    }
    
    Class B{
      void met(){
       com.example.Class2 c = new com.example.Class2();
     }
    }
    
    ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable
    
    NoClassDefFoundError extends LinkageError  extends Error extends Throwable
    
        public class MainClass
        {
            public static void main(String[] args)
            {
                try
                {
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                }catch (ClassNotFoundException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
    
    
        java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at pack1.MainClass.main(MainClass.java:17)
    
        class A
        {
          // some code
        }
        public class B
        {
            public static void main(String[] args)
            {
                A a = new A();
            }
        }
    
        Exception in thread "main" java.lang.NoClassDefFoundError: A
        at MainClass.main(MainClass.java:10)
        Caused by: java.lang.ClassNotFoundException: A
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)