Java中异常分哪两类,有什么区别?

典型回答 Java中的异常,主要可以分为两大类,即受检异常(checked exception)和 非受检异常(unchecked exception) 对于受检异常来说,如果一个方法在声明的过程中证明了其要有受检异常抛出: public void test() throws Exception{} 那么,当我们在程序中调用他的时候,一定要对该异常进行处理(捕获或者向上抛出),否则是无法编译通过的。这是一种强制规范。 这种异常在IO操作中比较多。比如FileNotFoundException ,当我们使用IO流处理一个文件的时候,有一种特殊情况,就是文件不存在,所以,在文件处理的接口定义时他会显示抛出FileNotFoundException,起目的就是告诉这个方法的调用者,我这个方法不保证一定可以成功,是有可能找不到对应的文件的,你要明确的对这种情况做特殊处理哦。 所以说,当我们希望我们的方法调用者,明确的处理一些特殊情况的时候,就应该使用受检异常。 对于非受检异常来说,一般是运行时异常,继承自RuntimeException。在编写代码的时候,不需要显式的捕获,但是如果不捕获,在运行期如果发生异常就会中断程序的执行。 这种异常一般可以理解为是代码原因导致的。比如发生空指针、数组越界等。所以,只要代码写的没问题,这些异常都是可以避免的。也就不需要我们显示的进行处理。 试想一下,如果你要对所有可能发生空指针的地方做异常处理的话,那相当于你的所有代码都需要做这件事。 知识扩展 **什么是**Throwable Throwable是java中最顶级的异常类,继承Object,实现了序列化接口,有两个重要的子类:Exception和 Error,二者都是 Java 异常处理的重要子类,各自都包含大量子类。 Error和Exception的区别和联系 error表示系统级的错误,是java运行环境内部错误或者硬件问题,不能指望程序来处理这样的问题,除了退出运行外别无选择,它是Java虚拟机抛出的。如OutOfMemoryError、StackOverflowError�这两种常见的错误都是ERROR。 exception 表示程序需要捕捉、需要处理的异常,是由与程序设计的不完善而出现的问题,程序必须处理的问题。分为RuntimeException和其他异常 请列举几个常用的RuntimeException。 这个题目,其实面试官考的还挺多的,主要是考察面试者实战经验是否丰富,所以常见的RuntimeException要能回答的尽量多回答一些。 AnnotationTypeMismatchException, ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DataBindingException, DOMException, EmptyStackException, EnumConstantNotPresentException, EventException, FileSystemAlreadyExistsException, FileSystemNotFoundException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, IllformedLocaleException, ImagingOpException, IncompleteAnnotationException, IndexOutOfBoundsException, JMRuntimeException, LSException, MalformedParameterizedTypeException, MirroredTypesException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NoSuchMechanismException, NullPointerException, ProfileDataException, ProviderException, ProviderNotFoundException, RasterFormatException, RejectedExecutionException, SecurityException, SystemException, TypeConstraintException, TypeNotPresentException, UndeclaredThrowableException, UnknownEntityException, UnmodifiableSetException, UnsupportedOperationException, WebServiceException, WrongMethodTypeException ...

March 22, 2026 · 1 min · santu

以下关于异常处理的代码有哪些问题

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public static void start() throws IOException, RuntimeException{ throw new RuntimeException("Not able to Start"); } public static void main(String args[]) { BufferedReader br = null; try { String line; br = new BufferedReader(new FileReader("\home\usr\test.java")); while ((line = br.readLine()) != null) { start(); } return; } catch (Exception ex) { ex.printStackTrace(); } catch (RuntimeException re) { re.printStackTrace(); } finally { // 是否会输出? System.out.print("1"); } } 典型回答 #start方法不会发生IOException,所以不需要throws RuntimeExcption不需要显式的throws catch的时候,要先从子类开始catch,代码中catch的顺序不对 没有关闭流 return之前的finally block是会被执行的 知识扩展 上述代码,如何优化 1 2 3 4 5 6 7 8 9 10 public static void main(String... args) { try (BufferedReader br = new BufferedReader(new FileReader("\home\usr\test.java"))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { // handle exception } } try-with-resource的原理 javac使用了语法糖进行优化 ...

March 22, 2026 · 2 min · santu

finally中代码一定会执行吗?

典型回答 ✅final、finally、finalize有什么区别 通常情况下,finally的代码一定会被执行,但是这是有一个前提的,: 1、对应 try 语句块被执行, 2、程序正常运行。 如果没有符合这两个条件的话,finally中的代码就无法被执行,如发生以下情况,都会导致finally不会执行: 1、System.exit()方法被执行 2、Runtime.getRuntime().halt()方法被执行 3、try或者catch中有死循环 4、操作系统强制杀掉了JVM进程,如执行了kill -9 5、其他原因导致的虚拟机崩溃了 6、虚拟机所运行的环境挂了,如计算机电源断了 7、如果一个finally是由守护线程执行的,那么是不保证一定能执行的,如果这时候JVM要退出,JVM会检查其他非守护线程,如果都执行完了,那么就直接退出了。这时候finally可能就没办法执行完。 ✅什么是守护线程,和普通线程有什么区别? 扩展知识 finally执行顺序 ✅try中return A,catch中return B,finally中return C,最终返回值是什么?

March 22, 2026 · 1 min · santu

Java中的枚举有什么特点和好处

枚举类型是指由一组固定的常量组成合法的类型。Java中由关键字enum来定义一个枚举类型 1 2 3 public enum Season { SPRING, SUMMER, AUTUMN, WINER; } Java中枚举的好处如下: 1、枚举的valueOf可以自动对入参进行非法参数的校验 Java 枚举提供了 valueOf 方法,它可以根据字符串值返回相应的枚举常量。如果传入的字符串不匹配任何枚举常量,valueOf 会抛出 IllegalArgumentException 异常,从而自动进行非法参数的校验。 1 2 3 4 5 6 7 8 9 10 11 12 public class EnumExample { public static void main(String[] args) { try { Season ss = Season.valueOf("SPRING"); // 合法参数 System.out.println(ss); // 输出 SPRING Season invalidSeason = Season.valueOf("HOLLIS"); // 非法参数,会抛出异常 } catch (IllegalArgumentException e) { System.out.println("Invalid Season: " + e.getMessage()); // 输出 Invalid Season: HOLLIS } } } 2、可以调用枚举中的方法,相对于普通的常量来说操作性更强 枚举可以定义方法,这使得每个枚举常量都可以具备独特的行为。与普通常量相比,枚举更具操作性和灵活性。 ...

March 22, 2026 · 3 min · santu

JDK新版本中都有哪些新特性?

典型回答 JDK 8中推出了Lambda表达式、Stream、Optional、新的日期API等 JDK 9中推出了模块化 JDK 10中推出了本地变量类型推断 JDK 12中增加了switch表达式 JDK 13中增加了text block JDK 14中增加了Records JDK 14中增加了instance模式匹配 JDK 15中增加了封闭类 JDK 17中扩展了switch模式匹配 JDK 21(LTS)中增加了协程 JDK 25(LTS)中简化了main函数的写法。。。 (以上没有把所有版本都列出是因为某些版本的特性并不重要,或者开发者不太需要关注) 扩展知识 本地变量类型推断 在Java 10之前版本中,我们想定义定义局部变量时。我们需要在赋值的左侧提供显式类型,并在赋值的右边提供实现类型: 1 MyObject value = new MyObject(); 在Java 10中,提供了本地变量类型推断的功能,可以通过var声明变量: 1 var value = new MyObject(); 本地变量类型推断将引入“var”关键字,而不需要显式的规范变量的类型。 其实,所谓的本地变量类型推断,也是Java 10提供给开发者的语法糖。 虽然我们在代码中使用var进行了定义,但是对于虚拟机来说他是不认识这个var的,在java文件编译成class文件的过程中,会进行解糖,使用变量真正的类型来替代var Switch 表达式 在JDK 12中引入了Switch表达式作为预览特性。并在Java 13中修改了这个特性,引入了yield语句,用于返回值。 而在之后的Java 14中,这一功能正式作为标准功能提供出来。 在以前,我们想要在switch中返回内容,还是比较麻烦的,一般语法如下: 1 2 3 4 5 6 7 8 9 10 11 12 int i; switch (x) { case "1": i=1; break; case "2": i=2; break; default: i = x.length(); break; } 在JDK13中使用以下语法: ...

March 22, 2026 · 3 min · santu

现在JDK的最新版本是什么?

典型回答 目前Java的发布周期是每半年发布一次,大概在每年的3月份和9月份都会发布新版本。 ~~在2023年9月份的时候发布了JDK 21~~~~。 ~~ 2024年3月19日,JDK22正式发布~~~~。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ~~**<font style="color:rgb(34, 34, 38);">2024年9月17日JDK23正式发布</font>**~~ **<font style="color:rgb(34, 34, 38);"></font>** **<font style="color:rgb(34, 34, 38);">2025年3月18日JDK24正式发布</font>** **<font style="color:rgb(34, 34, 38);"></font>** **<font style="color:rgb(34, 34, 38);">2025年9月16日JDK25正式发布</font>** 根据正常的发布节奏,接下来的发布情况应该是: 2026-03 ——> JDK 26 2026-09 ——> JDK 27 2027-03 ——> JDK 28 在JDK 22及之前的版本中,最后一个LTS版本(Long Term Support)是JDK 25。

March 22, 2026 · 1 min · santu

char能存储中文吗?

典型回答 在Java中,char类型是用来表示一个16位(2个字节)的Unicode字符,它可以存储任何Unicode字符集中的字符,当然也包括中文字符。 例如: 1 2 char ch = '龗'; System.out.println(ch); // 输出:龗 但是,有人说,Java中的char是没办法表示生僻字的,这么说其实有点绝对了。 因为Unicode字符集包含了几乎所有的字符,包括常见字符、生僻字、罕见字以及其他语言的字符。所以,用char类型其实是可以存储生僻字的。 但是,在处理生僻字时,需要确保Java源代码文件本身以及编译器和运行时环境都支持Unicode字符集。另外,如果在字符串中使用生僻字,也需要注意字符编码和字符串长度的问题。 还有一点需要注意,Unicode字符集的目标是覆盖世界上所有的字符。然而,由于生僻字的数量庞大且不断增长,Unicode字符集可能无法及时收录所有生僻字。这主要取决于Unicode标准的版本以及生僻字的使用频率和普及程度。 虽然Unicode字符集也在一直不断的迭代更新,但是对于一些非常罕见的生僻字,它们可能因为版本问题,或者时间问题,暂时不在Unicode字符集中。在这种情况下,可能就会无法表示。

March 22, 2026 · 1 min · santu

ClassNotFoundException和NoClassDefFoundError的区别是什么?

典型回答 ClassNotFoundException是一个受检异常(checked exception)。他通常在运行时,在类加载阶段尝试加载类的过程中,找不到类的定义时触发。通常是由Class.forName()或类加载器loadClass或者findSystemClass时,在类路径中没有找到指定名称的类时,会抛出该异常。表示所需的类在类路径中不存在。这通常是由于类名拼写错误或缺少依赖导致的。 如以下方式加载JDBC驱动: 1 2 3 4 5 6 7 8 9 10 11 12 13 public class MainClass { public static void main(String[] args) { try { Class.forName("oracle.jdbc.driver.OracleDriver"); }catch (ClassNotFoundException e) { e.printStackTrace(); } } } 当我们的classpath中没有对应的jar包时,就会抛出这个ClassNotFoundException。 NoClassDefFoundError是一个错误(error),它表示运行时尝试加载一个类的定义时,虽然找到了类文件,但在加载、解析或链接类的过程中发生了问题。这通常是由于依赖问题或类定义文件(.class文件)损坏导致的。也就是说这个类在编译时存在,运行时丢失了,就会导致这个异常。 如以下情况,我们定义A类和B类, 1 2 3 4 5 6 7 8 9 10 11 12 class A { // some code } public class B { public static void main(String[] args) { A a = new A(); } } 在编译后会生成A.class和B.class,当我们删除A.class之后,单独运行B.class的时候,就会发生NoClassDefFoundError ...

March 22, 2026 · 1 min · santu

while(true)和for(;;)哪个性能好?

典型回答 while(true)和for(;;)都是做无限循环的代码,他俩有啥区别呢? 关于这个问题,网上有很多讨论,说那么多没用,直接反编译,看看字节码有啥区别就行了。 准备两段代码: 1 2 3 4 5 6 7 8 public class HollisTest { public static void main(String[] args) { for(;;){ System.out.println("this is hollis testing...."); } } } 1 2 3 4 5 6 7 8 public class HollisTest { public static void main(String[] args) { while (true){ System.out.println("this is hollis testing...."); } } } 分别将他们编译成class文件: ...

March 22, 2026 · 2 min · santu

Arrays.sort是使用什么排序算法实现的?

典型回答 Arrays.sort是Java中提供的对数组进行排序的方法,根据参数类型不同,它提供了很多重载方法: 1 2 3 4 public static void sort(Object[] a) ; public static void sort(byte[] a) public static void sort(float[] a) public static void sort(int[] a) 而针对不同的参数类型,采用的算法也不尽相同,首先,对于比较常见的基本数据类型(如int、double、char等)的数组,就是采用JDK 1.7中引入的**“双轴快速排序”(Dual-Pivot QuickSort)**: 1 2 3 public static void sort(int[] a) { DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); } 这里的DualPivotQuicksort.sort就是双轴快速排序的具体实现。 双轴快速排序是对传统快速排序的改进,它通过选择两个轴值来划分数组,并在每个划分区域中进行递归排序。这种算法通常比传统的快速排序更快,特别是在大量重复元素的情况下。双轴快速排序算法是在JDK7中引入的,并在后续版本中进行了优化和改进。 而针对另外一种类型,对于对象数组的排序,它支持两种排序方式,即归并排序和TimSort: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // 1.7以前 public static void sort(Object[] a) { Object[] aux = (Object[])a.clone(); mergeSort(aux, a, 0, a.length, 0); } // 1.7以后 public static void sort(Object[] a) { if (LegacyMergeSort.userRequested) legacyMergeSort(a); else ComparableTimSort.sort(a, 0, a.length, null, 0, 0); } /** To be removed in a future release. */ private static void legacyMergeSort(Object[] a) { Object[] aux = a.clone(); mergeSort(aux, a, 0, a.length, 0); } 这里面的MergeSort指的就是归并排序,这个算法是老版本中设计的,后续的版本中可能会被移除,新版本中主要采用TimSort算法。 ...

March 22, 2026 · 1 min · santu

留言给博主