异常
- 处理异常的格式
public static void main(String[] args) {// 可能会出异常的代码,需要使用try来处理,try不能单独使用,必须配合finally或catch使用try {int i = 10 / 0;System.out.println(i);} catch(Exception e) { // 捕获异常// 获取异常信息String message = e.getMessage();System.out.println("异常信息:" + message);// 一定要打印e.printStackTrace()e.printStackTrace();} finally { //最终都会执行的(当有必须程序需要处理时)System.out.println(111);}System.out.println(222);}# 运行结果异常信息:/ by zero111222
- 抛出异常
static void f1() throws Exception {try {int i = 10/0;System.out.println(i);} catch (Exception e) {// 捕获到异常后抛出异常,丢到方法名的后面throw new Exception();}}// f1()方法抛出了1个异常,main方法中调用时就需要main方法处理异常public static void main(String[] args) throws Exception {// 将异常抛给他的父级处理f1();}
- 捕获多个异常时,因为程序是从上往下运行,所以小的异常类型必须放在前面
static Integer f(String str) {try {return Integer.parseInt(str);} catch (ArrayIndexOutOfBoundsException e) {System.out.println("捕获到异常");} catch(NumberFormatException e) {e.printStackTrace();} catch (ClassCastException e) {System.out.println("类型转换");} catch (Exception e) {System.out.println("最大的异常");}return 0;}// 测试public static void main(String[] args){try {int f;f = f("111a");System.out.println(f);} catch (Exception e) {e.printStackTrace();}}
- 自定义异常
// 自定义的异常类需继承Throwable、Exception、RuntimeExceptionpublic class MyException extends RuntimeException {// 实现序列化idprivate static final long serialVersionUID = 1L;MyException() {super();}MyException(String msg) {super(msg);}}public class Test {static void f(String str) throws MyException{try {int i = Integer.parseInt(str);} catch (MyException e) {System.out.println("111");throw new MyException("类型转换错误");}}public static void main(String[] args) {f("a");}}
-
throw和throws的区别:throw在方法体内,表示抛出异常的动作throws表示可能会抛出的异常类型
-
异常处理的方式:try-catch或throwstry放可能出现异常的代码,catch捕获后处理;throws在方法头部抛出异常,交给方法的调用者处理
泛型
- 集合中使用泛型
// 给集合指定泛型,那么该集合中只能存入该类型的数据public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("adc");}
- 方法中使用泛型
// 格式:访问修饰符 [static] <T> void 方法名(T t){ 方法体} //可传多个参数public class Test {// 泛型方法public static < E > void printArray( E[] inputArray ) {// 输出数组元素for ( E element : inputArray ){System.out.printf( "%s ", element );}System.out.println();}}
- 判断是否是泛型方法
# 格式:访问修饰符 [static] <T> void 方法名(T t){方法体}public void f(){ # 普通方法}public T f() { # 类泛型化后的方法}public void f(T t) { # 普通方法,传入的参数可以是泛型}public <T> void f(T t){ # 泛型方法}
- 类中使用泛型
public class Box<T> {private T t;public void add(T t) {this.t = t;}public T get() {return t;}// 测试:main方法中new一个泛型类的对象,调用其中的方法public static void main(String[] args) {Box<Integer> integerBox = new Box<Integer>();Box<String> stringBox = new Box<String>();integerBox.add(new Integer(10));stringBox.add(new String("菜鸟教程"));System.out.printf("整型值为 :%d\\n\\n", integerBox.get());System.out.printf("字符串为 :%s\\n", stringBox.get());}}
- 接口中使用泛型,参考
public interface Interface01 <M>{public abstract void f1(M m);}public class Interface01impl<M> implements Interface01<M>{@Overridepublic void f1(M m) {System.out.println(m);}}public class Interface02impl implements Interface01<String> {@Overridepublic void f1(String s) {System.out.println(s);}}
- 类型通配符 ?
public class Test {// 为List集合指定类型统配符号public static void getData(List<?> data) {System.out.println("data :" + data.get(0));}// 若是使用泛型,则集合只能存入一种类型// 若是使用通配符,则可以接受任意不确定类型public static void main(String[] args) {List<String> name = new ArrayList<String>();List<Integer> age = new ArrayList<Integer>();List<Number> number = new ArrayList<Number>();name.add("icon");age.add(18);number.add(314);getData(name);getData(age);getData(number);}}
- 泛型边界
// 格式:<? extends ClassName>// 为通配符指定一个类型,则该集合只能接受这种类型public class Test {public static void getUperNumber(List<? extends Number> data) {System.out.println("data :" + data.get(0));}public static void main(String[] args) {List<String> name = new ArrayList<String>();List<Integer> age = new ArrayList<Integer>();List<Number> number = new ArrayList<Number>();name.add("icon");age.add(18);number.add(314);//getUperNumber(name);//1getUperNumber(age);//2getUperNumber(number);//3}}
- 超类型通配符
// 父类public class Fruit {}// 子类public class Apple extends Fruit {}// 使用超类型通配符// Apple、Orange类继承了Fruit类,使用超类型通配符可存入父类和子类的类型// 格式:<? super 父类>public class Test {// 1. 声明泛型方法static <T extends Apple> void f(T t) {}public static void main(String[] args) {// 2. 调用泛型方法;f(new Apple());f(new Orange());// 报错:<? extends ClassName> 不能往里存,只能取数据List<? extends Apple> l = new ArrayList<Apple>();// l.add(new Apple());l.add(null);System.out.println(l.get(0));// **超类型通配符使用方式:集合中添加当前类及其子类**List<? super Fruit> l2 = new ArrayList<Fruit>();l2.add(new Orange());l2.add(new Fruit());l2.add(new Apple());}}
- 总结
# 泛型边界:T的类型只能是当前ClassName或ClassName的子类<T extends ClassName># 通配符? 不能存数据,只能取数据,具有任何从ClassName继承的类型的列表<? extends ClassName># 超类型通配符,声明通配符是有某个特定类的任何基类来界定的<? super ClassName># 无界通配符<?># 表示类型的上界,表示参数化类型的可能是T 或是 T的子类;即类型只能是T或T的子类<? extends T># 表示类型下界,表示参数化类型是此类型的超类型(父类型),直至Object;即类型只能是T或T的父类<? super T>