zoukankan      html  css  js  c++  java
  • java异常机制

    java异常机制


    1.NoClassDefFoundError 和 ClassNotFoundException 有什么区别?

    ClassNotFoundException

    ClassNotFoundException是一个检查异常。从类继承层次上来看,ClassNotFoundException是从Exception继承的,所以ClassNotFoundException是一个检查异常。
    当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,如果没有在classpath中查找到指定的类,就会抛出ClassNotFoundException。一般情况下,当我们使用Class.forName()或者ClassLoader.loadClass以及使用ClassLoader.findSystemClass()在运行时加载类的时候,如果类没有被找到,那么就会导致JVM抛出ClassNotFoundException。
      最简单的,当我们使用JDBC去连接数据库的时候,我们一般会使用Class.forName()的方式去加载JDBC的驱动,如果我们没有将驱动放到应用的classpath下,那么会导致运行时找不到类,所以运行Class.forName()会抛出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(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)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at MainClass.main(MainClass.java:7)
    

    NoClassDefFoundError

    NoClassDefFoundError异常,看命名后缀是一个Error。从类继承层次上看,NoClassDefFoundError是从Error继承的。和ClassNotFoundException相比,明显的一个区别是,NoClassDefFoundError并不需要应用程序去关心catch的问题。
    当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。比如当我们在new一个类的实例的时候,如果在运行是类找不到,则会抛出一个NoClassDefFoundError的错误。

    public class TempClass {
    }
    
    public class MainClass {
        public static void main(String[] args) {
            TempClass t = new TempClass();
        }
    }
    
    • 首先这里我们先创建一个TempClass,然后编译以后,将TempClass生产的TempClass.class文件删除,然后执行程序,输出:
    Exception in thread "main" java.lang.NoClassDefFoundError: TempClass
        at MainClass.main(MainClass.java:6)
    Caused by: java.lang.ClassNotFoundException: TempClass
        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)
        ... 1 more
    

    2.try-with-resources 和 multiple catch

    异常处理代码比较繁琐,比如我们需要写很多千篇一律的捕获代码,或者在 finally 里面做一些资源回收工作。随着 Java 语言的发展,引入了一些更加便利的特性,比如 try-with-resources 和 multiple catch,具体可以参考下面的代码段。在编译时期,会自动生成相应的处理逻辑,比如,自动按照约定俗成 close 那些扩展了 AutoCloseable 或者 Closeable 的对象。

    try (BufferedReader br = new BufferedReader(…);
         BufferedWriter writer = new BufferedWriter(…)) {// Try-with-resources
    // do something
    catch ( IOException | XEception e) {// Multiple catch
       // Handle it
    } 
    

    3.注意

    • 1.尽量不要捕获类似 Exception 这样的通用异常,而是应该捕获特定异常
    • 2.不要生吞(swallow)异常
    • 3.Throw early, catch late 原则
    • 4.异常性能
      • 1)try-catch 代码段会产生额外的性能开销,或者换个角度说,它往往会影响 JVM 对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的 try 包住整段的代码;与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句(if/else、switch)要低效。

      • 2)Java 每实例化一个 Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了。

  • 相关阅读:
    asp.net core 3.1 CreateDefaultBuilder默认启动解析
    VS2019安装扩展成功后,扩展不显示(未启用,也找不到选项)
    Redis持久化必知必会
    调试错误,请回到请求来源地,重新发起请求
    复制DataRow行 插入DataTabel
    mysql查看被锁住的表
    RedisHelper帮助类(转)
    C#接口的作用实例解析
    ASP.NET CORE 启动过程及源码解读(转)
    医疗行业&产品/技术交流群
  • 原文地址:https://www.cnblogs.com/fjf3997/p/13177009.html
Copyright © 2011-2022 走看看