java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError的区别

简介: java里生成对象有如下两种方式: 1: Object obj = new ClassName(); 直接new一个对象 2: Class clazz = Class.forName(ClassName); Object obj = clazz.newInstance(); 通过class loader动态装载一个类,然后获取这个类的实例同样是生成对象, 同样是生成对象, (一) 在编译期间 1:  在编译期间检查classpath, 如果没有类定义,编译没法通过。

java里生成对象有如下两种方式:

    1:    Object obj = new ClassName(); 直接new一个对象
    2:    Class clazz = Class.forName(ClassName);
Object obj = clazz.newInstance(); 通过class loader动态装载一个类,然后获取这个类的实例同样是生成对象,

同样是生成对象,

(一) 在编译期间

1:  在编译期间检查classpath, 如果没有类定义,编译没法通过。

2:  在编译期间是不会检查的,不过需要抛出或者自己catch ClassNotFoundException。

 运行期间,如果1编译时依赖的类不在classpath中(导致classloader装载失败),此时抛出的异常就是NoClassDefFoundError。而如果2在运行期间需要装载的类不在classpath中,抛出的则是ClassNotFoundException。

(二) 在运行期间

如果 1 编译时依赖的类不在classpath中(导致classloader装载失败),此时 抛出的异常就是 NoClassDefFoundError。

如果 2 在运行期间需要装载的类不在classpath中,抛出的则是 ClassNotFoundException。

 

ClassNotFoundException

  ClassNotFoundException这个错误,比较常见也好理解。

  原因:就是找不到指定的class。

  常见的场景就是:

  1 调用class的forName方法时,找不到指定的类

  2 ClassLoader 中的 findSystemClass() 方法时,找不到指定的类

  3 ClassLoader 中的 loadClass() 方法时,找不到指定的类

  开发者平时会有这样一种使用方法,类似JDBC加载驱动!

复制代码
 1 package test321;
 2 
 3 public class test {
 4  public static void main(String[] args) {
 5   try {
 6    Class.forName("test321.hello");
 7   } catch (ClassNotFoundException e) {
 8    e.printStackTrace();
 9   }
10  }
11 }
复制代码

  此时,程序会到当前的目录中寻找指定位置test321.hello这个class。

  并且这个类也是可以正常执行的。

  但是,我们修改一下加载的类名,这样显然是找不到指定的类的。

复制代码
 1 package test321;
 2 
 3 public class test {
 4  public static void main(String[] args) {
 5   try {
 6    Class.forName("test321.hello1");
 7   } catch (ClassNotFoundException e) {
 8    e.printStackTrace();
 9   }
10  }
11 }
复制代码

  此时就会报错!

复制代码
报错!
java.lang.ClassNotFoundException: test321.hello1
 at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.java:190)
 at test321.test.main(test.java:6)
复制代码

  原因就是找不到指定的string对应的class文件。

  NoClassDefFoundError

  这个就比较奇葩了,查找其他的资料是说,通过了编译,但是使用的时候,比如new的时候会出错。

  通过查找资料,搜集到如下的场景:

  1 类依赖的class或者jar不存在

  2 类文件存在,但是存在不同的域中

  3 大小写问题,javac编译的时候是无视大小的,很有可能你编译出来的class文件就与想要的不一样!这个没有做验证。

  

  针对上面的第二点,做了个关于包名的验证:

  另一种情况就是由于你通过了编译,但是这个类是有包名的,因此在编译时需要指定classpath,在使用的时候需要加上包名才可以。

  下面做了一个小例子!

  在没有包名的情况下,我们看一下正常情况是什么样子的。

1 public class test {
2  public static void main(String[] args) {
3   System.out.println("test");
4  }
5 }

  而如果这个类中包含包名,那么按照上面的方法编译,使用时就会报错!

复制代码
1 package ccc;
2 
3 public class test {
4  public static void main(String[] args) {
5   System.out.println("test");
6  }
7 }
复制代码

  很明显,报错信息中指出了包的信息!那么怎么办呢?

  在编译时,加上【   -d .   】这样可以把当前的目录加入到classpath中。

  在使用时,加上包名就可以了!

  也就是说,这个含有包名的类,编译时,需要指定classpath的路径,并且使用的时候指定包名全路径,才可以。

 

目录
相关文章
|
20天前
|
Java UED
Java Web 中forward 和 redirect 的区别
在Java Web开发中,页面跳转是构建用户界面和实现业务逻辑的重要组成部分。Forward(转发)和Redirect(重定向)是两种常见的跳转方式,它们分别具有不同的特点和适用场景。正确地选择和使用这两种跳转方式,有助于提高Web应用的性能、用户体验和代码可维护性。
20 4
|
14天前
|
安全 Java
【JAVA】在 Queue 中 poll()和 remove()有什么区别
【JAVA】在 Queue 中 poll()和 remove()有什么区别
|
14天前
|
Java API
【JAVA】final、finally、finalize 有什么区别?
【JAVA】final、finally、finalize 有什么区别?
|
14天前
|
Java
【JAVA】throw 和 throws 的区别?
【JAVA】throw 和 throws 的区别?
|
14天前
|
Java
【JAVA】Iterator 和 ListIterator 有什么区别?
【JAVA】Iterator 和 ListIterator 有什么区别?
|
2天前
|
安全 Java 编译器
Java中String、StringBuilder和StringBuffer的区别
Java中String、StringBuilder和StringBuffer的区别
|
11天前
|
Java
Java中 a+=b和a=a+b有什么区别?
Java中 a+=b和a=a+b有什么区别?
|
11天前
|
Java 开发者
Java中三种Set的实现类的用法和区别
Java中三种Set的实现类的用法和区别
|
14天前
|
存储 安全 Java
【JAVA】concurrentHashMap和HashTable有什么区别
【JAVA】concurrentHashMap和HashTable有什么区别
|
14天前
|
安全 Java
【JAVA】线程的run()和start()有什么区别?
【JAVA】线程的run()和start()有什么区别?