------- android培训、java培训、期待与您交流! ----------
异常就是java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。
在开发时,如果定义功能时,发现该功能会出现一些问题,应该将问题在定义功能时标示出来,这样调用者就可以在使用这个功能的时候,预先给出处理方式。
对异常的图片描述:
【可处理异常】——【处理方式】
1. 声明抛出。告诉调用者功能会有问题。通过throws关键字对问题声明在功能上。
2. 进行捕捉。可以使用针对性的捕捉代码块完成。
try
{
//需要被检测的代码。
}
catch(异常类 变量)//该变量用于检测抛出的异常对象。
{
//异常处理代码
}
finally
{
//一定会被执行的代码
}
【finally】
一定会被执行的代码。 主要用于释放资源等。无论是否发生异常,有些动作一定要执行,那么这些动作就可以定义在finally代码块中。
【注意:】System.exit(0);退出JVM,这时finally不会被执行到。
在进行异常捕捉时,代码块的不同组合情况。
1. try catch finally
2. try catch // 没有需要一定被执行的代码——不需要关闭资源的动作。
3. try finally // 异常并没有被处理,没有catch,而将异常进行对外声明,但是却涉及到了资源的调用,必须要功能内部关闭,就有了try 和 finally 的组合。
try、catch、finally语句块的执行:
自定义异常:
现实开发非常复杂,Java类库中的异常处理类已经不能满足要求,我们需要抛出一个新的异常:一个自己定义的异常
创建自己的异常类非常的简单,可以用下面的声明语言来定义:
class 自定义异常名 xtends Exception{…}
这里的extends Exception就是我们定义的这个异常类是从java类库中的Exception这个类派生的,也就是说,我们自定义的异常类可以拥有Exception,这个类的全部的内容,另外,还可以再写我们需要的内容在里面。们需要的内容在里面
class fushuexception extends Exception//自定义异常信息继承Exception ,让该类具备可抛性
{
/*private String msg;
fushuexception(String msg)
{
this.msg= msg;
}
public String getMessage()
{
return msg;
}
//方法1:将异常信息传递给父类
*/
int value;
fushuexception(String msg,int value)//(出现负数了,y)
{
super(msg);
this.value = value;
}
public int getvalue()
{
return value;
}
//方法2:将异常信息传递给父类
}
class Chu
{
int div(int x,int y)throws fushuexception//throws函数内抛出非运行时异常,如有多个用逗号隔开
{
if(y<0)
throw new fushuexception("出现负数了",y);//throw方法中抛出异常用于抛出异常对象,后边跟的是对象
return x/y;
}
}
class ChuFa
{
public static void main(String[] args)
{
Chu c = new Chu();
Try//Try{//可能产生问题的代码div();}
<span style="white-space:pre"> </span>这里如果不是最终调用者也可以转化后抛出异常
{
int s = c.div(4,-1);
}
catch (fushuexception e)Catch(异常类型 异常对象){//异常产生时候的处理代码}
{
System.out.println("除数出现负数了"+e.getvalue());//处理自定义的异常
System.out.println(e.toString());//出现负数了 得到详细的异常信息
}
System.out.println("结束......over");
}
}
当异常出现后,在子父类进行覆盖时,有了一些新的特点:
1:当子类覆盖父类的方法时,如果父类的方法抛出了异常,那么子类的方法要么不抛出异常要么抛出父类异常或者该异常的子类,不能抛出其他异常。
2:如果父类抛出了多个异常,那么子类在覆盖时只能抛出父类的异常的子集。
如果父类或者接口中的方法没有抛出过异常,那么子类是不可以抛出异常的,如果子类的覆盖的方法中出现了异常,只能try不能throws。如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。
如果多个catch中有父类异常,父类异常一定要定义在最下面。否则编译失败!
记住:finally很有用,主要用户关闭资源。无论是否发生异常,资源都必须进行关闭。
细节:
1. 如果一个功能抛出多个异常。那么在调用该功能时,需要有多个catch进行每一个异常的针对性处理;
2. 特殊部分:
函数内抛出异常,函数上一定要用throws标示,否则编译失败。
调用到声明异常的函数,要进行声明throws声明抛出,或者trycatch捕捉。
3.重点掌握 如果被覆盖的方法没有抛出异常,子类也不允许抛出异常。如果子类中真的出现异常,只能在子类方法内进行try处理,绝对不允许throws声明。 万一处理不了呢?你可以选择抛出运行时异常。
泛型
首先我们来看一个示例
import java.util.*;
class fanx
{
public static void main(String[] args)
{
Set set = new TreeSet();
set.add(1);
set.add(2);
set.add(3);
set.add(4);
System.out.println(set);
}
}
编译结果如图:
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
解决的办法就是,我们需要在容器上明确具体的数据类型。
泛型的好处
1. 将运行时期的ClassCastException异常转移到了编译时期,进行检查,并以编译失败来提示,这样有利于程序员尽早解决问题。
2. 避免了向下转型的麻烦。
泛型的擦除:
泛型技术是用于编译时期的技术,编译器会按照<>中的指定类型对元素进行检查, 检查不匹配,就编译失败,匹配,就编译通过,通过后,生成的class文件中时没有泛型的。这就是:泛型的擦除。
泛型类和泛型方法:
当一个类要操作的引用数据类型不确定时,可以为该类型定义一个形参。用到该类时,由使用者来通过传递类型参数的形式,来确定要操作的具体对象
这种将泛型定义在类上,用于接受具体的实参的类叫泛型类。
方法要操作的类型不确定,可以将泛型定义在方法上
静态方法不能访问类上定义的泛型,如果需要泛型,该泛型只能定义在方法上。
class too<T>//类上的泛型
{
public <T> void show(T t)//方法上的泛型,接收一个和泛型类一致的参数
{
System.out.println(t);
}
}
public class fanx {
public static void main(String[] args) {
too<String> t1 = new too<String>();//在建立对象的时候通过泛型指定对象的类型
too<Integer> t2 = new too<Integer>();
t1.show("haha");//调用方法
t2.show(1234);
}
}
泛型的通配符:
当操作的不同容器中的类型都不确定的时候,而且使用的都是元素从Object类中继承的方法。这时泛型就用通配符?比如:
private static void printColl(Collection<?> b) {
Iterator<?> it = b.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
泛型限定
对操作的类型限制在一个范围之内
extends E:接收E类型或者E的子类型。这就是上限。
super E: 下限:接收E类型或者E的父类型。这就是下限
import java.util.*;
class student
{
String name;
student(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class advstudent extends student
{
advstudent(String name)
{
super(name);
}
public String getName()
{
return name;
}
}
class comp implements Comparator<student>
{
public int compare(student s1,student s2)
{
return s1.getName().compareTo(s2.getName());
}
}
class studentdemo
{
public static void main(String[] args)
{
TreeSet<student> ts = new TreeSet<student>(new comp());
ts.add(new student("java1"));
ts.add(new student("java2"));
ts.add(new student("java3"));
ts.add(new student("java4"));
ts.add(new student("java5"));
print(ts);
TreeSet<advstudent> ts1 = new TreeSet<advstudent>(new comp());
ts1.add(new advstudent("java...01"));
ts1.add(new advstudent("java...02"));
ts1.add(new advstudent("java...03"));
ts1.add(new advstudent("java...04"));
print(ts1);
}
public static void print(TreeSet<? extends student> qqq)//限定接收学生和学生的子类
{
Iterator<? extends student> it = qqq.iterator();//这里迭代器上也使用了泛型
while (it.hasNext())
{
System.out.println(it.next().getName());
}
}
}