泛型
一、泛型概述
泛型可以在编译时候检查类型安全并且所有的强制转换都是自动和隐式的,在我们不清楚需要什么数据类型的时候使用泛型
二、泛型的使用
1.定义泛型类
格式:权限修饰符 class 类名<T>{}; T表示未知类型
public class GenericsDemo2<T> { T name; public static void main(String[] args) { //如果不声明泛型T的类型,T默认时Object类型 GenericsDemo2 gen=new GenericsDemo2(); gen.name=100; } }
2.定义泛型方法
格式:修饰符<泛型> 返回值类型 方法名(参数列表){
//方法体;
}
public void printName(){ System.out.println(name.getClass()); } //制定泛型方法:权限修饰符 <T> 返回值类型 方法名(T t) //参数传递的是什么类型 V就是什么类型 public <V> void test(V v){ System.out.println(v); }
测试:
//自定泛型类型为String T就是String GenericsDemo2<String> gener=new GenericsDemo2<>(); gener.name="www"; gener.printName(); gener.test(100);
3.定义泛型接口
格式:修饰符 interface 接口名{
void method(T t);
}
//泛型接口 public interface userService <T>{ void test(T t); }
//实现类 public class userServiceImpl implements userService<String> { @Override public void test(String s) { } } //实现类在实现接口是还不确定类型,在创建对象时确定 class userServiceImpl2<T> implements userService<T>{ @Override public void test(T t) { } public static void main(String[] args) { new userServiceImpl2(); } }
4.通配符的使用
//通配符 ? :一般在方法参数上使用 /* <? extends 类> 表示你定义的类型时该类的子类 <? super 类> 表示定义类型是该类的父类或者自己 */
public static void main(String[] args) { GenericsDemo3 gen=new GenericsDemo3(); ArrayList<Integer> list=new ArrayList<>(); ArrayList<String> list1=new ArrayList<>(); ArrayList<Number> list2=new ArrayList<>(); ArrayList<Object> list3=new ArrayList<>(); gen.test(list); // gen.test(list1);//报错 因为参数List指定类型必须是Number的子类 传递的是String不是Number的子类 gen.tesr1(list2); gen.tesr1(list3); }
异常
一、异常概述
程序在运行时,发生了的错误,它阻止了程序按照预期正常执行的流程,这就是异常。
异常发生的主要三个原因:
1.Java虚拟机产生的异常。
2.代码错误产生的异常。比如:空指针异常,数组越界异常。
3.手动生成的异常,一般用来告知方法的调用者一些注意事项。
为了能够及时有效地处理程序中的运行错误,Java专门引入了异常类。
(1)异常类
在Java中,所有异常类型都是Throwable的子类,Throwable类下有两个异常分支Exception和Error。
\1. Exception类用于程序可能出现的异常。
\2. Error一般是指JVM错误,通常环境下不希望被程序捕获的异常。
\3. 运行时异常(RuntimeException)也称为不检查异常,非运行异常也称为不检查异常。
(2)常见的运行时异常(RuntimeException)
这些异常一般是由程序逻辑错误引起的,可以通过修改代码来避免。
空指针异常:NullPointerException
下标越界异常:IndexOutOfBoundsException、
算术异常:ArithmaticException、
类型转换异常:ClassCastException)等
(3)常见的非运行时异常
这些异常必须进行捕获处理,或向上声明抛出。
IO异常:IOException
SQL异常:SQLException
类加载异常:ClassNotFoundException
解析异常:ParseException
(4)常见的Error错误
Error**错误大多发生在运行时,肯定会导致程序终止,我们不讨论如何对Error进行处理,因为它们**
通常是致命性错误,不是程序可以控制的。
NoClassDefFoundError:找不到 class 定义异常
StackOverflowError:深递归导致栈被耗尽而抛出的异常
OutOfMemoryError:内存溢出异常
二、捕获异常
//使用try...catch语句块去捕获异常 /* try{ 可能会出现异常的代码 }catch(捕获异常的类型 引用){ 处理异常的代码 } 1.如果try语句块中出现了异常,代码块将不会执行。此时catch捕获了异常,开始执行catch语句块中的代码 2.如果try语句块中没有异常,则不会执行catch语句块中的代码。跳过catch继续执行 3.catch中声明的异常可以捕获它的子类异常 4.在前面声明了捕获异常后下面的catch就不能捕获该异常的子类 */
1. 在catch到异常后,可以使用以下三个方法输出相应的异常信息。
(1)printStackTrace():指出异常的类型、性质、栈层次及出现在程序中的位置
(2)getMessage() 方法:输出错误的性质。
(3)toString() 方法:给出异常的类型与性质。
2. 在多个catch代码块的情况下,当一个catch代码块捕获到一个异常时,其它的catch代码块就不再进行。
3. catch中声明的异常能够捕获到它的子异常。当捕获的多个异常类之间存在父子关系时,捕获异
常时一般先捕获子类,再捕获父类。所以子类异常必须在父类异常的前面,否则子类捕获不到。
Scanner sc=new Scanner(System.in); int i=1; System.out.println("请输入除数"); try { int j=sc.nextInt(); System.out.println(i/j);//java.lang.ArithmeticException 算数异常 // }catch (ArithmeticException e){ System.out.println("除数不能为0"); }catch (InputMismatchException e){ System.out.println("输入错误"); }catch (Exception e){ //e.printStackTrace:打印异常的性质,类型,以及异常发生的位置(一般用此方法表示异常) //e.getMessage():打印异常性质 //e:异常性质和类型 e.printStackTrace(); } System.out.println("阿弥陀佛"); // //非运行时异常 // SimpleDateFormat format=new SimpleDateFormat(); // format.parse("www"); }
//格式:try...catch...finally //在finally语句块里面的代码,无论有没有异常 都会执行。一般用来关闭资源。要么try...catch 要么try...catch...finally
使用try-catch-finally语句注意事项:
1.try不能单独出现,要么try....catch,要么try...finally(不建议)。
2.catch和finally都不能单独出现,前面必须先有try。
三、声明和抛出异常
(1)throws
当一个方法中产生了一个异常时,要么使用try....catch捕获处理,要么不处理。不处理该异常就要使用throws进行抛出,将该异常传递到方法外部进行处理。
//throws: 一般使用在方法上 格式:throws 异常类型; //作用:表明该方法一旦出现了异常,不进行处理。把他抛给调用者处理 public class ExceptionDemo3 { public static void test()throws Exception{//不处理该异常,抛给调用者处理 Thread.sleep(30); System.out.println("休眠结束"); } public static void test1()throws Exception{//继续抛出异常 test(); } public static void main(String[] args) throws Exception {//交给虚拟机处理,就打印异常信息 test1(); } }
注意:
1.可以同时抛出多个异常,使用逗号分割。
2.使用throws抛出该异常时,该异常由调用者进行处理,如果调用者追溯到main方法,main方法也不知道该异常如何处理时,就交给JVM进行处理,打印异常信息,并终止程序运行
public class ExceptionDemo4 { } class Father{ void test() throws NullPointerException{ } } class Son extends Father{ //子类重写父类方法后,可以不处理该方法的异常,但是不能跑一个更大的异常 父类如果没有异常,子类也可以抛出异常0. @Override void test() throws NullPointerException { super.test(); } }
3.子类在重写父类方法时,子类重写后的方法声明抛出的异常类型应该和父类方法声明抛出的异常一致或者是其子类。
4.父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出。
(2)throw
throw语句用来直接抛出一个异常,使用在代码块中,当throw语句执行时,后面的语句将不再执行,寻找相匹配的catch语句,处理该异常。
public class ExceptionDemo5 { //随机生成一个六位数纯数字的验证码 提示输入验证码,若错误次数超过三次,抛出一个异常 提示次数用完程序终止运行 public static void test() throws XXXException { //生成随机数组 Random random=new Random(); ArrayList<Integer> list=new ArrayList<>(); for (int i = 0; i <6; i++) { list.add(random.nextInt(10)); } // System.out.println(list); String pwd=""; for (int i = 0; i < list.size(); i++) { pwd+=list.get(i); } // System.out.println(pwd); //键盘输入验证码 Scanner sc=new Scanner(System.in); String inpet; int count=0; System.out.println("请输入验证码"); do { System.out.println("验证码"+pwd); inpet= sc.next(); // if (inpet.length()!=6){ // System.out.println("请输入正确验证码"); // } count++; if (count==3){ throw new XXXException("错误次数超过三次,停止运行"); } }while(!inpet.equals(pwd) &&inpet.length()!=6); System.out.println("输入正确"); } public static void main(String[] args) throws XXXException { test(); } }
throws和throw的区别:
1.throws出现在方法上,throw出现在代码中。
2.throws表示出现异常的一种可能性,并不是一定会发生异常,表明一旦发生异常我不处理,交给
调用者去处理。但throw一旦声明就明确在这里就要抛出异常。
四、自定义异常
上述接触到的异常,都是一个个的类,并且继承了Exception。我们也可以自己定义一个异常类,并
且根据异常类型继承一个异常父类。
结构:
定义一个编译期异常 class XXXException extends Exception
定义一个运行期异常 class XXXException extends RuntimeException
自定义异常类一般包含两个构造方法:
1.一个是无参的构造方法。
2.另一个构造方法以字符串的形式接收一个定制的异常消息,并将该消息传递给父类的构造方法
//自定义一个异常类
public class XXXException extends Exception{
//无参构造
public XXXException() {
}
//有参构造,并且使用super调用父类的构造方法,传递异常信息
public XXXException(String message) {
super(message);
}
}
//将上述代码throw异常,改为我们自定义的异常
if(accout.length()>10 || accout.length()<5) {
throw new XXXException("账号长度需在5~10之间");
}