java基础(四)
1.36 遇到过异常吗,如何处理?
在Java中,可以按照如下三个步骤处理异常:
-
捕获异常
将业务代码包裹在try块内部,当业务代码中发生任何异常时,系统都会为此异常创建一个异常对象。创建异常对象之后,JVM会在try块之后寻找可以处理它的catch块,并将异常对象交给这个catch块处理。
-
处理异常
在catch块中处理异常时,应该先记录日志,便于以后追溯这个异常。然后根据异常的类型、结合当前的业务情况,进行相应的处理。比如,给变量赋予一个默认值、直接返回空值、向外抛出一个新的业务异常交给调用者处理,等等。
-
回收资源
如果业务代码打开了某个资源,比如数据库连接、网络连接、磁盘文件等,则需要在这段业务代码执行完毕后关闭这项资源。并且,无论是否发生异常,都要尝试关闭这项资源。将关闭资源的代码写在finally块内,可以满足这种需求,即无论是否发生异常,finally块内的代码总会被执行。
1.37 说一说Java的异常机制
参考答案
关于异常处理:
在Java中,处理异常的语句由try、catch、finally三部分组成。其中,try块用于包裹业务代码,catch块用于捕获并处理某个类型的异常,finally块则用于回收资源。当业务代码发生异常时,系统会创建一个异常对象,然后由JVM寻找可以处理这个异常的catch块,并将异常对象交给这个catch块处理。若业务代码打开了某项资源,则可以在finally块中关闭这项资源,因为无论是否发生异常,finally块一定会执行。
关于抛出异常:
当程序出现错误时,系统会自动抛出异常。除此以外,Java也允许程序主动抛出异常。当业务代码中,判断某项错误的条件成立时,可以使用throw关键字向外抛出异常。在这种情况下,如果当前方法不知道该如何处理这个异常,可以在方法签名上通过throws关键字声明抛出异常,则该异常将交给JVM处理。
关于异常跟踪栈:
程序运行时,经常会发生一系列方法调用,从而形成方法调用栈。异常机制会导致异常在这些方法之间传播,而异常传播的顺序与方法的调用相反。异常从发生异常的方法向外传播,首先传给该方法的调用者,再传给上层调用者,以此类推。最终会传到main方法,若依然没有得到处理,则JVM会终止程序,并打印异常跟踪栈的信息
1.38 请介绍Java的异常接口
- Throwable是异常的顶层父类,它由两个直接子类error和,exception
- error是与jvm相关的问题
- exception又分为编译时异常和运行时异常,编译时异常是提醒你这个地方可能会出错,而运行时异常则可能是由于程序员逻辑不严谨引起的
1.39 finally是无条件执行的吗?
不管try块中的代码是否出现异常,也不管哪一个catch块被执行,甚至在try块或catch块中执行了return语句,finally块总会被执行。
1.40 在finally中return会发生什么?
参考答案
在通常情况下,不要在finally块中使用return、throw等导致方法终止的语句,一旦在finally块中使用了return、throw语句,将会导致try块、catch块中的return、throw语句失效。
1.41 说一说你对static关键字的理解
- java类中包含成员变量,构造器,代码块,方法,内部类5种成员,static可以修饰成员变量,代码块,方法及内部类
- 被static修饰的成员是类成员,属于整个类,不属于某个实例
- 类成员不能访问实例成员,因为类成员在类加载的时就初始化,实例成员在创建一个实例时才初始化
1.42 static修饰的类能不能被继承?
参考答案
static修饰的类可以被继承。
扩展阅读
如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。因此使用static修饰的内部类被称为类内部类,有的地方也称为静态内部类。
static关键字的作用是把类的成员变成类相关,而不是实例相关,即static修饰的成员属于整个类,而不属于单个对象。外部类的上一级程序单元是包,所以不可使用static修饰;而内部类的上一级程序单元是外部类,使用static修饰可以将内部类变成外部类相关,而不是外部类实例相关。因此static关键字不可修饰外部类,但可修饰内部类。
静态内部类需满足如下规则:
-
静态内部类可以包含静态成员,也可以包含非静态成员;
-
静态内部类不能访问外部类的实例成员,只能访问它的静态成员;
-
外部类的所有方法、初始化块都能访问其内部定义的静态内部类;
-
在外部类的外部,也可以实例化静态内部类,语法:外部类.内部类 变量名 = new 外部类.内部类构造方法()
1.43 static和final有什么区别?
static关键字可以修饰成员变量、成员方法、初始化块、内部类,被static修饰的成员是类的成员,它属于类、不属于单个对象。以下是static修饰这4种成员时表现出的特征:
- 类变量:被static修饰的变量称为类变量(静态变量),它随类的信息存在于方法区,建议通过类名访问
- 类方法:被static修饰的方法(静态方法),类方法属于类,建议通过类名访问
- 静态块:被static修饰的代码块叫做静态初始化块,在类加载时调用一次,之后便不会调用了
- 静态内部类:被static修饰的内部类叫静态内部类。静态内部类不能访问外部类的实例成员,只能访问外部类的静态成员。外部类的所有方法、初始化块都能访问其内部定义的静态内部类。
final关键字可以修饰类,成员变量,方法
- final修饰的类不能被继承
- final修饰的方法不能被重写
- final修饰的变量一旦初始化便不能在被修改
1.44 说一说你对泛型的理解
- 泛型可以在编译阶段约束操作的数据类型,避免了运行时可能出现的强制类型转换异常
- 泛型只能支持引用类型
- 泛型可以在类,方法,接口上定义
1.45 介绍一下泛型擦除
泛型只在编译时约束操作的数据类型,在编译成字节码文件进入运行阶段时都会转换成真实数据类型,相当于泛型被擦除了
反射是作用在运行时的技术,可以绕过编译阶段为集合添加任意类型的数据
可以把一个具有泛型信息的List可以直接赋给另一个没有泛型信息的List
1.46 List<? super T>和List<? extends T>有什么区别?
-
? 是类型通配符,List<?> 可以表示各种泛型List的父类,意思是元素类型未知的List;
-
List<? super T> 用于设定类型通配符的下限,此处 ? 代表一个未知的类型,但它必须是T的父类型;
-
List<? extends T> 用于设定类型通配符的上限,此处 ? 代表一个未知的类型,但它必须是T的子类型。
1.47 说一说你对Java反射机制的理解
- 反射是指对于任何一个Calss类,在“运行的时候”都可以得到这个类的全部成分
- 在运行时可以得到这个类的构造器,成员变量,成员方法
- 这种运行时动态获取类信息以及动态调用类种成分的能力的机制叫做反射
- 核心和关键就是得到编译以后的class文件对象
1.48 Java反射在实际项目中有哪些应用场景?
-
面向切面编程(AOP)的实现方案,是在程序运行时创建目标对象的代理类,这必须由反射机制来实现。