目录
一、Java异常类
1.异常类是什么
异常指的并不是语法错误,语法错了编译不通过,不会产生字节码文件,根本不能运行。所谓异常就是程序运行时可能出现的一些错误,比如试图打开一个根本打不开的文件等,异常处理将会改变程序的控制流程,让程序有机会对错误做出处理。
在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象,Java处理异常的方式是中断处理。
Java 使用 throw 关键字抛出一个 Exception 子类的实例表示异常发生。例如,java.lang 包中的 Integer 类调用其类方法 public static int parse Int(String s)可以将“数字”格式的字符,如"6789”,转化为 int 型数据,但是当试图将字符串"ab89"转换成数字时,例如:
int number = Integer.parseInt("ab89");
方法 parseInt()在执行过程中就会抛出 NumberFormatException 对象(使用 throw 关键字拋出一个 NumberFormatException 对象),即程序运行出现 Number FormatException 异常。
Java 允许定义方法时声明该方法调用过程中可能出现的异常,即允许方法调用过程中抛出异常对象,终止当前方法的继续执行。
2.Throwable中的常用方法
异常对象可以调用如下方法得到或输出有关异常的信息
public String getMessage();//获取发生异常的原因。提示给用户的对候,就提示错误的原因。
public void printStackTrace();//打印异常的详细信息。包含了异常的类型、异常的原因,还包括异常出现的位置在开发和调试阶段都得使用。
public String toString();//获取异常的类型和异常描述信息(不用)。
3.Throwable体系
异常机制其实是帮助我们找到程序中的问题,异常的根类是java.lang.Throwable,其下有两个子类,java.lang.Error与Java.lang.Exception,平常所说的异常指java.lang.Exception。
- Error:严重错误Error ,无法通过处理的错误,只能事先避免。
- Exception:表示异常,异常产生后程序员可以通过代码的方式糾正,使程序继续运行,是必须要处理的。
4.异常产生的过程
public class Main {
public static void main(String[] args) {
//创建int类型的数组,并赋值
int[] arr={1,2,3};
int e=getElement(arr,3);
System.out.println(e);
}
/*
定义一个方法,获取数组指定索引处的元素
参数:
int[] arr
int index
*/
public static int getElement(int []arr,int index){
int ele = arr[index];
return ele;
}
}
(1)访问数组3索引,而数组没有3索引,JVM会检测出程序出现异常
JVM会根据异常产生的原因创建一个异常对象,这个异常对象包含了异常产生的(内容、原因、位置)
在getElement方法中,没有异常的处理逻辑(try,catch),那么JVM就会把异常对象抛出给方法的调用者main方法来处理这个异常
(2)main方法接收到了这个异常对象,main方法也没有异常的处理逻辑,继续把对象抛出给main方法的调用者JVM处理
(3)JVM接收到了这个异常对象,把异常对象(内容、原因、位置)以红色的字体打印在控制台,JVM会终止当前正在执行的java程序→中断处理
5.异常的处理
Java异常处理的五个关键字:throw、throws、try、catch、finally
- throw关键字
作用:在指定的方法中抛出指定的异常
格式:throw new XXXException("异常产生的原因");
注:
1.throw必须写在方法的内部
2.throw后边new的对象必须是Exception或者Exception的子类对象
3.throw抛出指定的异常对象,我们就必须处理这个对象。如果后边创建的是RuntimeException或者RuntimeException的子类对象,我们可以不予处理,交给JVM处理(打出异常对象,中断程序)
- throws关键字
作用:运用于方法声明之上,用于表示当前方法。不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)
声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译的异常,而没有捕获处理,那么必须通过throws进行声明,让调用者去处理。
格式:修饰符 返回值类型 方法名(参数)throws 异常类名1,异常类名2...{ }
注:
1.throws必须写在方法声明处
2.throws后边声明的异常必须是Exception或者是Exception的子类
3.方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常。如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可
4.调用了一个声明抛出异常的方法,我们就必须处理声明的异常。要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM处理→中断处理;要么try...catch自己处理异常
- 捕获异常try...catch
注:
1.try中可能会抛出多了异常对象,那么就可以使用多个catch来处理这些异常对象
2.如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的逻辑值,继续执行try...cach之后的代码
3.如果try中没有异常,那么就不会执行catch中的异常处理逻辑,执行完try中的代码,继续执行try...cach之后的代码
格式:
try{ 可能产生异常的代码 }catch(定义一个异常的变量,用来接受try中抛出的异常对象){ 异常的处理逻辑,产生异常对象之后,怎么处理异常对象 } ... catch(异常类名 变量名){ }
- finally代码块
作用:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转 ,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。
当我们在try语句块中打开了一些物理资源(磁盘文件/网络连接/数据库连接等),我们都得在使用完之后,最終关闭打开的资源。
格式:try..catch...finally:自身需要处理异常,最終还得关闭资源。
注:
1.finally不能单独使用。
二、Java常用类
1.String类
由于在程序设计中经常涉及处理和字符序列有关的算法,为此Java专门提供了用来处理字符序列的String类。String类在java.lang 包中,由于java.lang 包中的类被默认引入,因此程序可以直接使用String类。需要注意的是Java把 String 类定义为final类,因此用户不能扩展String 类,即 String类不可以有子类。
2.stringTokenizer类
String Tokenizer类是一个用来分隔String的应用类。
有时需要分析String对象的字符序列并将字符序列分解成可被独立使用的单词,这些单词叫作语言符号。例如,对于"You are welcome",如果把空格作为分隔标记,那么"You arewelcome"就有三个单词(语言符号);而对于"You,are,welcome",如果把逗号作为分割标记,那么"You,are,welcome"有三个单词。
当分析一个 String对象的字符序列并将字符序列分解成可被独立使用的单词时,可以使用java.util 包中的StringTokenizer类,该类有两个常用的构造方法。
StringTokenizer(String s):为String对象s构造一个分析器。使用默认的分隔标记,即空格符、换行符、回车符、Tab符、进纸符做分隔标记。
StringTokenizer(String s, String delim):为String对象s构造一个分析器。参数delim的字符序列中的字符的任意排列被作为分隔标记。
例如:
StringTokenizer fenxi = new StringTokenizer ("you are welcome");
StringTokenizer fenxi = new StringTokenizer ("you#*are*##welcome","#*");
3.Scanner类
Scanner对象可以解析字符序列中的单词,例如,对于String对象NBA
String NBA ="I Love This Game";
为了解析出 NBA的字符序列中的单词,可以如下构造一个Scanner对象:
Scanner scanner = new Scanner (NBA);
Scanner对象可以调用方法
useDelimiter(正则表达式);
将正则表达式作为分隔标记,即让 Scanner对象在解析操作时,把与正则表达式匹配的字符序列作为分隔标记。如果不指定分隔标记,那么Scanner对象默认地用空白字符(空格、制表符、回行符)作为分隔标记来解析String 对象的字符序列中的单词。
4.StringBuffer类
String对象的字符序列是不可修改的,也就是说,String对象的字符序列的字符不能被修改、删除,即 String对象的实体是不可以再发生变化的。
与String类不同,StringBuffer类的对象的实体的内存空间可以自动地改变大小,便于存放一个可变的字符序列。
例如:对象s可调用append方法追加一个字符序列
StringBuffer s='new StringBuffer("我喜欢");
s.append("玩篮球"");
5.Date类与Calendar类
- Date类
使用 Date类的无参数构造方法创建的对象可以获取本机的当前日期和时间
Date nowTime = new Date();
Date datel=new Date(1000);
date2=new Date(-1000);
- Calendar类
Calendar类在java.util 包中。使用Calendar类的static方法 getInstance()可以初始化一个日历对象
Calendar calendar = Calendar.getInstance();
然后calen可以调用方法:
public final void set(int year,int month, int date)
public final void set(int year,int month,int date,int hour,int minute)
public final void set(int year,int month,int date, int hour,int minute,int second)
6.Math类、BigInteger类、Random类
- Math类
在编写程序时,可能需要计算一个数的平方根、绝对值或获取一个随机数等。java.lang 包中的Math类包含许多用来进行科学计算的static方法,这些方法可以直接通过类名调用。另外,Math类还有两个 static常量:E和 PI,二者的值分别是2.7182828284590452354和3.14159265358979323846。
常用方法:
public static long abs(double a):返回a的绝对值。
public static double max(double a,double b):返回a、b的最大值。
public static double min(double a,double b):返回a、b的最小值。
public static double random():产生一个0~1之间的随机数(不包括0和1)。
public static double pow(double a,double b):返回a的b次幂。
public static double sqrt(double a):返回a的平方根。
public static double log(double a):返回a的对数。
public static double sin(double a):返回a的正弦值。
public static double asin(double a):返回a的反正弦值。
public static double ceil(double a):返回大于a的最小整数,并将该整数转化为double型数据
public static double floor(double a):返回小于a的最大整数,并将该整数转化为double型数据。
public static long round(double a):返回值是(long)Math.floor(a+0.5)),即所谓a的“四舍五入”后的值
- BigInteger类
程序如果需要处理特别大的整数,就可以用java.math包中的BigInteger类的对象。可以使用构造方法 public BigInteger(String val)构造一个十进制的 BigInteger对象。该构造方法可以发生NumberFormatException异常,也就是说,字符串参数val中如果含有非数字字符就会发生NumberFormatException异常。
常用方法:
public BigInteger add(BigInteger val):返回当前对象与val的和。
public BigInteger subtract(BigInteger val):返回当前对象与val的差。
public BigInteger multiply(BigInteger val):返回当前对象与val的积。
public BigInteger divide(BigInteger val):返回当前对象与val的商。
public BigInteger remainder(BigInteger val):返回当前对象与val的余。
public int compareTo(BigInteger val):返回当前对象与val的比较结果,返回值是1、-1或0,分别表示当前对象大于、小于或等于val。
public BigInteger abs():返回当前整数对象的绝对值。
public BigInteger pow(int a):返回当前对象的a次幂。
public String toStringO:返回当前对象十进制的字符串表示。
public String toString(int p):返回当前对象p进制的字符串表示。
- Random类
更为灵活的用于获得随机数的Random类(该类在java.util包中)。
public Random();
public Random (long seed);
7.Class类与Console类
Class是 java.lang 包中的类,该类的实例可以帮助程序创建其他类的实例。创建对象最常用的方式就是使用new运算符和类的构造方法,实际上也可以使用Class对象得到某个类的实例。
如果希望在键盘输入一行文本,但不想让该文本回显,即不在命令行显示,那么就需要使用java.io包中的 Console类的对象来完成。
8.Pattern类与Match类
模式匹配就是检索和指定模式匹配的字符序列。Java提供了专门用来进行模式匹配的Pattern类和 Matcher类,这些类在java.util.regex包中。
三、容器
Java的容器主要分为2个大类,即Collection和Map。
Collection代表着集合,类似数组,只保存一个数字。
Map则是映射,保留键值对两个值。
- List 有序集合,允许重复的元素
ArrayList:底层用Object数组实现,特点是查询效率高,增删效率低,线程不安全
LinkedList:底层使用双向循环链表实现,特点是查询效率低,增删效率高,线程不安全,因为线程不同步。
Vector:底层用长度可以动态增长的对象数组实现,它的相关方法用 Synchronized 进行了线程同步,所以线程安全,效率低。
Stack:栈。特点是:先进后出。继承于Vector
- Set: 无序集合,不允许重复的元素
HashSet:底层用HashMap实现,本质是一个简化版的HashMap,因此查询效率和增删效率都比较高。其add方法就是在map中增加一个键值对,键对象就是这个元素,值对象是PRESENT的对象LinkedHashSet:继承自HashSet,内部使用的是LinkHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。
TreeSet:底层用TreeMap实现,底层是一种二叉查找树(红黑树),需要对元素做内部排序。内部维持了一个简化版的TreeMap,并通过key来存储Set元素。使用时,要对放入的类实现Comparable接口,且不能放入null。
- Map集合
HashMap:采用散列算法来实现,底层用哈希表来存储数据,因此要求键不能重复。线程不安全,HashMap在查找、删除、修改方面效率都非常高。允许key或value为null。
四、泛型
1、泛型的概念
Java 型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体的值,那样这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
2、泛型的好处
- 保证了类型的安全性
- 消除强制转换
- 避免了不必要、拆箱操作 ,提高程序的性能
- 提高了代码的重用性
定义格式:
public class 类名 <泛型类型1,...>{
}
通常类型参数我们都使用大写的单个字母表示:
T:任意类型 type
E:集合中元素的类型 element
K:key-value形式 key
V: key-value形式 value