1、异常
有异于常态,和正常情况不一样,有错误出现。阻止当前方法或作用域,称之为异常。
2、异常的处理
对于异常的正确处理,能够将异常提示给编程人员或者是用户,使本来已经中断的程序以适当的方式继续运行或者是退出,并且能够保存用户的当前操作或者进行回滚,最后再把占用的资源释放掉。
3、JAVA中异常的分类
1.java中的所有不正常类都继承于Throwable类。Throwable主要包括两个大类,一个是Error类,另一个是Exception类;
2.其中Error类中包括虚拟机错误和线程死锁,一旦Error出现了,程序就彻底的挂了,被称为程序终结者;
3.Exception类主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类,非检查异常(RuntimeException)和检查异常(其他的一些异常)
4.RuntimeException主要包括以下四种异常:空指针异常、数组下标越界异常、类型转换异常、算术异常
5.运行时异常会由java虚拟机捕获,运行时异常一般说明java代码有问题,应该从逻辑上改进代码
6.检查异常主要包括:文件异常(IOException)和SQL异常(SQLException)等
7.检查异常需要手动的捕获处理
4、处理异常
try-catch以及try-catch-finally
try{
//一些会抛出异常的方法
}catch(Exception e){
//处理该异常块的代码
}catch(Exception2 e){
//处理Exception2的代码
}finally{
//最终将要执行的一些代码
}
如果try中的方法抛出异常,首先这个方法会终止执行,然后程序的控制权会交由catch块中的异常处理程序。
如果try中的方法抛出多个异常,就用到多重处理,在try块后用多个catch块来捕获多个类型的异常,并对其进行相应的处理
编写多重语句块要从小到大,通过先子类后父类的方法来编写catch语句块,这是因为程序抛出异常时,异常处理系统会就近寻找异常程序,而子类继承于父类,对于父类的异常处理程序,子类也是适用的。如果catch块的顺序写错了,编译器在编译的时候也是不会通过的。
如果用try-catch语句块处理完后还需要一些善后工作,例如关闭连接,或者是关闭一些已经打开了的文件,这些善后工作可以用finally语句块来实现
printStackTrace()这个方法可以打印异常信息
5、Java中的异常抛出
throws是写在方法名和方法的参数表之后,在方法体之前,用它修饰的方法向调用者表明,该方法可能会抛出某种类型的异常,这里可以只抛出一种类型也可以抛出多种类型,每个异常的中间用逗号隔开就可以了,具体的方法体里面可以调用一些会抛出异常的方法,或者可以新抛出一个异常,就用到了throw关键字,throw是一个动词,写在方法体里面,表明的就是具体的抛出异常这个动作,如果某个方法调用到了会抛出异常的方法,那么必须添加try catch语句去捕获这种异常,或者添加throws声明,将异常丢给更上一层的去进行处理
public void 方法名(参数列表) throws 异常列表{
//调用会抛出异常的方法或者:
throw new Exception();
}
自定义异常,就是自己声明定义的异常类型,自定义异常必须继承于JAVA类库中意思相近的异常类型,或者直接继承于所有类型的基类,也就是exception类型
class 自定义异常类 extends 异常类型{
}
6、JAVA中的异常链
有时我们可以把捕获的异常包装成一个新的异常,然后在新的异常里添加对原始异常的引用,再把这个新异常抛出,它们就像是链式反应一样,一个导致另一个,在JAVA中这种情况就叫做异常链
7、实际应用中的经验与总结
1.处理运行时异常,可以采用优化代码,用逻辑加以控制,去合理规避的同时还可以辅助加上try-catch处理
2.在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
3.对于调用的其他方法,并不确定是否会抛出其他异常,也可以加上try-catch,来捕获或处理潜在的异常,
4.对于异常,要尽量去处理,不去处理,在健壮性上就会大打折扣,切忌只是简单的调用printStackTrace()去打印输出,最好是在打印输出处理异常的时候加上其他操作,比如说业务回滚等等
5.具体如何处理异常,要根据不同的业务需求和异常类型去决定
6.尽量添加finally语句块去释放占用的资源,尤其是有网络连接和连接数据库的情况下
8、Java中的字符串
在java中,字符串被作为String类型的对象处理,String类位于java.lang包中,默认情况下,该包被自动导入所有的程序
创建String对象的方法:
String s1 = "imooc";
String s2 = new String();
String s3 = new String("imooc");
9、Java中字符串的不变性
String对象创建后则不能被修改,是不可变的,所谓的修改其实是创建了新的对象,所指向的空间不同
一旦一个字符串在内存中创建,则这个字符串将不可改变,如果需要一个可以改变的字符串,我们可以使用StringBuffer或者StringBuilder
每次new一个字符串就是产生一个新的对象,即便两个字符串的内容相同,使用"=="比较时也为"false"
10、JAVA中String类的常用方法
1.字符串str中字符的索引从0开始,范围从0到str.length()-1
2.使用indexOf进行字符或字符串查找时,如果匹配返回位置索引;如果没有匹配结果,返回-1
3.使用substring(beginIndex,endIndex)进行字符串截取时,包括beginIndex位置的字符,不包括endIndex位置的字符
4.==和equals的区别
==:判断两个字符串在内存中首地址是否相同,即判断是否是同一个字符串对象(char一定要用单引号)
equals():比较存储在两个字符串对象中的内容是否一致
11、StringBuilder类
String类具有不可变性,用String类频繁操作字符串的时候,会产生很多额外的临时变量
使用StringBuilder类或者StringBuffer类就可以避免这个问题,
StringBuilder和StringBuffer类基本相似,不同之处就是,StringBuffer类是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高一些。因此一般情况下,如果要创建一个内容可变的字符串对象,应优先考虑使用StringBuilder类
12、StringBuilder类的常用方法
追加和插入操作,修改了str的值,而没有创建新的对象,这就是StringBuilder和String类最大的区别
13、Java中的包装类
包装类主要提供了两大类方法:
1.将本类型和其他基本类型进行转换的方法
2.将字符串和本类型及包装类互相转换的方法
Integer包装类的常用方法:
14、Java中基本类型和包装类之间的转换
JDK1.5引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更加轻松便利了。
装箱:把基本类型转换成包装类,使其具有对象的性质,又可分为手动装箱和自动装箱
拆箱:和装箱相反,把包装类对象转换成基本类型的值,又可分为手动拆箱和自动装箱
15、Java中基本类型和字符串之间的转换
基本类型转换为字符串有三种方法:
1.使用包装类的toString()方法
2.使用String类的value()Of方法
3.用一个空字符串加上基本类型,得到的就是基本类型数据对应的字符串
将字符串转换成基本类型有两种方法:
1.调用包装类的parseXxx静态方法
2.调用包装类的valueOf()方法转换为基本类型的包装类,会自动拆箱
16、使用Date和SimpleDateFormat类表示时间
处理日期和时间的相关数据可以使用java.util包中的Date类。这个类最主要的作用就是获取房钱时间。
使用Date类的默认无参构造方法创建出的对象就代表当前时间,我们可以直接输出Date对象显示当前的时间,显示结果如下:
如果想按制定的格式进行显示,如2018-05-13 13:14:00,可以使用java.text包中的SimpleDateFormat来对日期时间进行格式化,如可以将日期转换为指定格式的文本,也可将文本转换为日期
1.使用format()方法,将日期转换为制定格式的文本
yyyy表示四位年,MM表示月,dd表示年,HH表示小时(24小时制),mm表示分钟,ss表示秒,这样就制定了转换的目标格式,这就组成了预定义字符串,最后调用format()方法将时间转换为指定的格式的字符串
2.使用parse()方法将文本转换为日期
调用parse方法将文本转换为日期
注意:
调用SimpleDateFormat对象的parse()方法时可能会出现转换异常,即ParseException,因此需要进行异常处理
使用Date类时需要导入java.util包,使用SimpleDateFormat时需要导入java.text包
17、Calendar类
Date类最主要的作用是获取当前时间,但是由于本身设计问题,不建议使用,更推荐使用Calendar类进行时间和日期的处理
java.util.Calendar类时一个抽象类,可以通过调用getInstance()静态方法获取一个Calendar对象,此对象已由当前日期时间初始化,即默认代表当前时间,如Calendar c = Calendar.getInstance();
其中,调用Calendar类的getInstance()方法获取一个实例,然后通过调用get()方法获取日期时间信息,参数为需要获得的字段的值,Calendar.Year等为Calendar类中定义的静态常量。
Calendar类提供了getTime()方法,用来获取Date对象,完成Calendar和Date的转换,还可通过getTimeInMillis()方法,获取此Calendar的时间值,以毫秒为单位,如下:
18、Math类操作数据
Math类位于java.lang包中,包含用于执行基本数学运算的方法,Math类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如:Math.round();
常用的方法如下:
19、Java中的集合框架
集合的概念:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象
集合的作用:
在类的内部,对数据进行组织;
简单而快速的搜索大数量的条目;
有的集合接口,提供了一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关元素
有的集合接口,提供了映射关系,可以通过关键字(key)去快速找到对应的唯一对象,而这个关键字可以是任意类型
与数组的对比一为何选择集合而不是数组
数组的长度固定,集合长度可变
数组只能通过下标访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象
20、泛型
集合中的元素,可以是任意类型的对象(对象的引用)
如果把某个对象放入集合的话,就会忽略他的类型,而把他当做object处理
泛型则是规定了某个集合只可以存放特定类型的对象
会在编译期间进行类型检查
可以直接按指定类型获取集合元素
泛型集合可以添加泛型的子类型的实例
泛型集合中的限定类型不能使用基本数据类型
可以通过使用包装lei限定允许存入的基本数据类型
21、Set
Set是元素无序且不可以重复的集合,被称为集
HashSet-哈希集,是Set的一个重要的实现类
循环遍历Set只能用foreach方法或者iterator方法,不能用get()方法,因为Set是无序的,所以每次出来的结果应该是不一样的
Set中可以添加null,但是实际中没什么用
22、Map&HashMap
Map接口
Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据KEY快速查找value,
Map中的键值对以Entry类型的对象实例形式存在
键(key值)不可重复,value可以
每个键最多只能映射到一个值
Map接口提供了分别返回key值集合、value值集合以及Entry(键值对)集合的方法
Map支持泛型,形式如:Map<K,V>