泛型的由来:通过Object转型问题引入--为了解决安全隐患
早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换异常的问题
提高安全性(将运行期的错误转换到编译期)
省去强转的麻烦,取出数据不再是Object,不需要强转,能确定其类型
<>中放的必须是引用数据类型
前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
不要定义成Object,因为没有意义
泛型类:把泛型定义在类上
定义格式:public class 类名
泛型方法:把泛型定义在方法上
定义格式:public 返回类型 方法名(泛型类型 变量名)
泛型接口:把泛型定义在接口上
定义格式:public interface 接口名,implements接口时需要给定泛型
泛型通配符:表示任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E:向下限定,E及其子类
? super E:向上限定,E及其父类
异常:Java程序在运行过程中出现的错误
分类:Error服务器宕机,数据库崩溃等;Exception
编译异常:因为程序编码存在问题,必须处理,否则无法通过编译
运行异常:运行时出现的问题,通常因为编码考虑不周导致
Throwable
Error
Exception
RuntimeException
...
Throwable是Exception的父类(继承体系)
getMessage() //获取异常信息,返回字符串
toString() //获取异常类名和异常信息,返回字符串
printStackTrace() //获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void,jvm默认的处理方式也是这种
方法内出现异常,如果方法内没有进行处理,那么会将异常抛给调用者,如果到最后都没有处理会交由JVM处理
JVM默认是如何处理异常的:抛出一个异常对象,异常名称和信息输出到控制台,终止运行程序
异常只要在程序内进行了处理,后续代码仍然可以执行
try 检测异常
catch 捕获异常,并在catch方法体内进行处理
catch可以有多个,针对不同异常进行不同处理
try,但是不catch,那么异常仍然会向上抛出
finally 必要操作,如释放资源
注意事项:
1.try部分的代码,只要遇到第一个异常以后,就会寻求异常处理,处理异常以后,try部分的代码也不会执行,但会继续执行其他部分代码
2.jdk1.7以后,可以用 | 的形式用一个catch接受多种异常
作用:finally语句体一定会执行,除非在执行到finally之前jvm退出了(比如System.exit(0))
注意:finally在整个方法的return前执行,不过即使finally中操作了返回值相关的变量,也并不能改变最终return的值,但如果finally中做了return,那么显然本来要执行的return也就没有机会执行了
应用:用于释放资源,在IO流操作和数据库操作中常见
应用:需要把方法异常交由调用者处理,就用throw把异常对象抛出,再通过throws在方法上标识,如果方法中声明了多种throw异常,那么throws也要多种,逗号隔开
throws和throw的区别
throws(通知调用者)
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throw(通知本方法)
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
指定异常并抛出,交由调用者处理,后续代码不再继续执行
作用:适应具体的业务场景,比如人的年龄超过200岁,抛出异常年龄错误
创建自定义异常类:
继承Exception,要throws
继承RuntimeException,可以不throws(通常不这么干)
子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类(父亲坏了,儿子不能比父亲更坏)
如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws