从初面到终面JAVA面试系列(八)

目录

一、面试问题

二、参考答案


一、面试问题

71.静态变量会被序列化吗?

72.Error和Exception区别是什么?

73.非受检查异常(运行时异常)和受检查异常(一般异常)区别是什么?

74.throw和throws的区别是什么?

75.NoClassDefFoundError和ClassNotFoundException区别?

76.Java常见异常有哪些?

77.try-catch-finally中哪个部分可以省略?

78.try-catch-finally中,如果catch中return了,finally还会执行吗?

79.JVM是如何处理异常的?

80.Java的IO流分为几种?

二、参考答案

71.静态变量会被序列化吗?

不会。因为序列化是针对对象而言的,而静态变量优先于对象存在,随着类的加载而加载,所以不会被序列化.

看到这个结论,是不是有人会问,serialVersionUID也被static修饰,为什么serialVersionUID会被序列化?其实serialVersionUID属性并没有被序列化,JVM在序列化对象时会自动生成一个serialVersionUID,然后将我们显示指定的serialVersionUID属性值赋给自动生成的serialVersionUID。

72.Error和Exception区别是什么?

Java中,所有的异常都有一个共同的祖先java.lang包中的Throwable类。Throwable类有两个重要的子类Exception(异常)和Error(错误)。

Exception和Error二者都是Java异常处理的重要子类,各自都包含大量子类。

Exception:程序本身可以处理的异常,可以通过catch来进行捕获,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。Exception又可以分为运行时异常(RuntimeException,又叫非受检查异常)和非运行时异常(又叫受检查异常)。

Error:Error属于程序无法处理的错误,我们没办法通过catch来进行捕获。例如,系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复。

73.非受检查异常(运行时异常)和受检查异常(一般异常)区别是什么?

非受检查异常:包括RuntimeException类及其子类,表示JVM在运行期间可能出现的异常。Java编译器不会检查运行时异常。例如:NullPointException(空指针)、NumberFormatException(字符串转换为数字)、IndexOutOfBoundsException(数组越界)、ClassCastException(类转换异常)、ArrayStoreException(数据存储异常,操作数组时类型不一致)等。

受检查异常:是Exception中除RuntimeException及其子类之外的异常。Java编译器会检查受检查异常。常见的受检查异常有:IO相关的异常、ClassNotFoundException、SQLException等。

非受检查异常和受检查异常之间的区别:是否强制要求调用者必须处理此异常,如果强制要求调用者必须进行处理,那么就使用受检查异常,否则就选择非受检查异常。

74.throw和throws的区别是什么?

Java中的异常处理除了包括捕获异常和处理异常之外,还包括声明异常和拋出异常,可以通过throws关键字在方法上声明该方法要拋出的异常,或者在方法内部通过throw拋出异常对象。

throws关键字和throw关键字在使用上的几点区别如下:

throw关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。

throws关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用throws标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法签名中用throws关键字声明相应的异常。

举例如下:

throw关键字:

public static void main(String[]args){

String s="abc";

if(s.equals("abc")){

throw new NumberFormatException();

}else{

System.out.println(s);

}

//function();

}

throws关键字:

public static void function()throws NumberFormatException{

String s="abc";

System.out.println(Double.parseDouble(s));

}

public static void main(String[]args){

try{

function();

}catch(NumberFormatException e){

System.err.println("非数据类型不能转换。");

//e.printStackTrace();

}

}

75.NoClassDefFoundError和ClassNotFoundException区别?

NoClassDefFoundError是一个Error类型的异常,是由JVM引起的,不应该尝试捕获这个异常。引起该异常的原因是JVM或ClassLoader尝试加载某类时在内存中找不到该类的定义,该动作发生在运行期间,即编译时该类存在,但是在运行时却找不到了,可能是变异后被删除了等原因导致。

ClassNotFoundException是一个受检查异常,需要显式地使用try-catch对其进行捕获和处理,或在方法签名中用throws关键字进行声明。当使用Class.forName,ClassLoader.loadClass或ClassLoader.findSystemClass动态加载类到内存的时候,通过传入的类路径参数没有找到该类,就会抛出该异常;另一种抛出该异常的可能原因是某个类已经由一个类加载器加载至内存中,另一个加载器又尝试去加载它。

76.Java常见异常有哪些?

java.lang.IllegalAccessError:违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常。

java.lang.InstantiationError:实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.

java.lang.OutOfMemoryError:内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。

java.lang.StackOverflowError:堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出或者陷入死循环时抛出该错误。

java.lang.ClassCastException:类造型异常。假设有类A和B(A不是B的父类或子类),O是A的实例,那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。

java.lang.ClassNotFoundException:找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

java.lang.ArithmeticException:算术条件异常。譬如:整数除零等。

java.lang.ArrayIndexOutOfBoundsException:数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。

java.lang.IndexOutOfBoundsException:索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常。

java.lang.InstantiationException:实例化异常。当试图通过newInstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常。

java.lang.NoSuchFieldException:属性不存在异常。当访问某个类的不存在的属性时抛出该异常。

java.lang.NoSuchMethodException:方法不存在异常。当访问某个类的不存在的方法时抛出该异常。

java.lang.NullPointerException:空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。

java.lang.NumberFormatException:数字格式异常。当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。

java.lang.StringIndexOutOfBoundsException:字符串索引越界异常。当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常。

77.try-catch-finally中哪个部分可以省略?

catch可以省略。更为严格的说法其实是:try只适合处理运行时异常,try+catch适合处理运行时异常+普通异常。也就是说,如果你只用try去处理普通异常却不加以catch处理,编译是通不过的,因为编译器硬性规定,普通异常如果选择捕获,则必须用catch显示声明以便进一步处理。而运行时异常在编译时没有如此规定,所以catch可以省略,你加上catch编译器也觉得无可厚非。

理论上,编译器看任何代码都不顺眼,都觉得可能有潜在的问题,所以你即使对所有代码加上try,代码在运行期时也只不过是在正常运行的基础上加一层皮。但是你一旦对一段代码加上try,就等于显示地承诺编译器,对这段代码可能抛出的异常进行捕获而非向上抛出处理。如果是普通异常,编译器要求必须用catch捕获以便进一步处理;如果运行时异常,捕获然后丢弃并且+finally扫尾处理,或者加上catch捕获以便进一步处理。

至于加上finally,则是在不管有没捕获异常,都要进行的“扫尾”处理。

78.try-catch-finally中,如果catch中return了,finally还会执行吗?

会执行,在return前执行。

在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,就会返回修改后的值。显然,在finally中返回或者修改返回值会对程序造成很大的困扰,Java中也可以通过提升编译器的语法检查级别来产生警告或错误。代码示例1:

public static int getInt(){

int a=10;

try{

System.out.println(a/0);

a=20;

}catch(ArithmeticException e){

a=30;

return a;

/*

*return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了

*但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40

*再次回到以前的路径,继续走return 30,形成返回路径之后,这里的a就不是a变量了,而是常量30

*/

}finally{

a=40;

}

return a;

}

//执行结果:30

代码示例2:

public static int getInt(){

int a=10;

try{

System.out.println(a/0);

a=20;

}catch(ArithmeticException e){

a=30;

return a;

}finally{

a=40;

//如果这样,就又重新形成了一条返回路径,由于只能通过1个return返回,所以这里直接返回40

return a;

}

}

//执行结果:40

79.JVM是如何处理异常的?

在一个方法中如果发生异常,这个方法会创建一个异常对象,并转交给JVM,该异常对象包含异常名称,异常描述以及异常发生时应用程序的状态。创建异常对象并转交给JVM的过程称为抛出异常。可能有一系列的方法调用,最终才进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈。

JVM会顺着调用栈去查找看是否有可以处理异常的代码,如果有,则调用异常处理代码。当JVM发现可以处理异常的代码时,会把发生的异常传递给它。如果JVM没有找到可以处理该异常的代码块,JVM就会将该异常转交给默认的异常处理器(默认处理器为JVM的一部分),默认异常处理器打印出异常信息并终止应用程序。          

80.Java的IO流分为几种?

按照流的方向:输入流(inputStream)和输出流(outputStream);

按照实现功能分:节点流(可以从或向一个特定的地方读写数据,如FileReader)和处理流(是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写,BufferedReader);

按照处理数据的单位:字节流和字符流。分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的。

从初面到终面:JAVA面试系列之java基础面试题及答案:

https://download.csdn.net/download/qq_29633789/88405523

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电阻电容及电线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值