Java第九篇反射和异常处理

上一篇已经介绍了C#类和java类的区别,由于工作原因经过三天的间断整理才合完,以备后面复习时对比。这里把发射单独做一篇讲解。

通过java反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问,检测,和修改描述Java对象本身信息的功能,Java反射机制的功能十分强大,在Java。lang。reflect包中提供了对该功能的支持。所有的类都继承了object类,在object类中定义了getclass方法,该方法返回一个类型为class的对象。格式:Class 对象名 = 对象。getClass(),得到的对象名可以访问很多方法,

举例说明:访问构造方法,将返回Constructor类型的对象或数组,每个Constructor对象代表一个构造方法,利用Constructor对象可以操作相应的构造方法。,如访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问,例如访问一个入口参数类型依次为String 和int型的构造方法,1.对象名。getDeclaredConstructor(String.class, int.Class)2.对象名。getDeclaredConstructor(new Class [] {String.class, int.Class})而Constructor对象又有很多方法可以运用,

利用java。lang。reflect。modifier 类可以解析出getModifiers()方法返回的值所表示的修饰符的信息,该功能可以查看该构造函数被什么修饰符修饰。

同理Field中常用的方法


Method类中常用的方法



反射有三种实现方法:

第一种方法,forName()静态方法:Class.forName(String str);

// 注意:str - 所需类的完全限定名。

Class class1 = Class.forName("com.mzsds.fanshe.fanshe");

// 第二种方法,.class

Class class2 = String.class;

// 第三种方法,.getClass();

fanshe fs = new fanshe();

Class class3 = fs.getClass();

最后:利用反射可以调用类的私有方法,也可以调用父类的私有方法,当调用父类的私有方法时需要特殊处理,因为可能获取不到,以下为转载的链接

注意调用私有成员前要 constructor/Field/method(各种对象).setAccessible(true);

https://blog.csdn.net/woshinia/article/details/11766567

这里练习的时候了解了下java异常处理机制

Throwable类是所有异常类的超类,该类的两个直接子类是Error和Exception。其中Error及子类用于指示合理的应用程序不应该试图捕获的严重问题,Expection及其子类给出了合理应用程序需要捕获的异常。

可控式异常:

IOExpection:当发生某种I/0异常时,抛出此异常

SQLExpection:提供关于数据库访问错误的其他错误信息异常

ClassNotFoundExpection:没找到类的异常

NoSuchFieldExpection:类不包含指定的字段

NoSuchMethodExpection:无法找到某一特定方法,抛出该异常。

运行时异常:

IndexOutofBoundsExpection:数组或者集合超出界限,

NullPointerExpection:访问对象为null时的异常

ArithmeticExpection:异常的运算条件时的异常,

IllegalArgumentExpection:表明向方法传递了一个不合法或者不正确的参数

ClassCastExpection:当试图讲对象转换为不是实例的子类时抛出该异常。

获取异常信息:

getlocalizedMessage()返回Throwable的本地化描述,

getMessage()获取此throwable的详细信息字符串 ,

printStackTrace()将此Throwable及其栈踪迹输出至标准错误流

tostring()获取此throwable的剪短描述

在一个方法的运行过程中,如果发生了异常,则Java虚拟机生成一个代表该异常的对象(它包含了异常的详细信息),并把它交给运行时系统,运行时系统寻找相应的代码来处理这一异常。我们把生成异常对象并把它提交给运行时系统的过程称为抛出(throw)一个异常

运行时系统寻找相应的代码来处理这一异常,系统在方法的调用栈中查找,从产生异常的方法开始进行回朔,沿着被调用的顺序往前寻找,直到找到包含相应异常处理的方法为止。这一过程称为捕获(catch)一个异常

格式:

try{

正常程序段,可能抛出异常;

}

catch (异常类1  异常变量) {

捕捉异常类1有关的处理程序段;

}

catch (异常类2  异常变量) {

捕捉异常类2有关的处理程序段;

}

……

finally{

一定会运行的程序代码;

}

l  try块——捕获异常:用于监控可能发生异常的程序代码块是否发生异常,如果发生异常,Try代码块将抛出异常类所产生的对象并立刻结束执行,而转向异常处理catch部分。

对于系统产生的异常或程序块中未用try监控所产生的一场,将一律由java 编译系统自动将异常对象抛出。

l  catch块——处理异常 :抛出的异常对象如果属于catch内所定义的异常类,则catch会捕获该异常,并进入catch中的对应代码段继续运行程序,如果异常对象不属于catch中所定义的异常类,则进入finally块继续运行程序。

Catch包括两个参数:一个是类名,指出捕获的异常类型,必须使Throwable类的子类;一个是参数名,用来引用被捕获的对象。Catch块所捕获的对象并不需要与它的参数类型精确匹配,它可以捕获参数中指出的异常类的对象及其所有子类的对象

l  finally块——最终处理:无论是否发生异常都会执行的语句块。比如执行关闭打开的文件、删除临时文件,关闭数据库连接等操作。

 

注意:

l  一个try、catch、finally块之间不能插入任何其它代码

l  catch可以有多个,try和finally只能有一个

l  try后面必须要跟catch、finally其中的一个,即但一个try、catch、finally语句只能省略catch、finally中的一个。

定义多个catch可精确地定位java异常。如果为子类的异常定义了特殊的catch块,而父类的异常则放在另外一个catch块中,此时,必须满足以下规则:子类异常的处理块必须在父类异常处理块的前面,否则会发生编译错误。所以,越特殊的异常越在前面处理,越普遍的异常越在后面处理。这类似于 制订防火墙的规则次序:较特殊的规则在前,较普通的规则在后。

异常类常用方法

常用非法

用途

Void String getMessage()

返回异常对象的一个简短描述

Void String toString()

获取异常对象的详细信息

Void printStackTrace()

在控制台上打印异常对象和它的追踪信息

 

异常的抛出可以分为两大类:

l  系统自动抛出异常

比如上面的例子就是系统自动抛出异常,通过try catch捕获异常对象,并继续相应的处理。

 

l  通过关键字throw将异常对象显性地抛出。

即在程序中生成自己的异常对象,即异常可以不是出错产生,而是人为编写代码主动抛出。显性抛出异常从某种程度上实现了将处理异常的代码从正常流程代码中分离开了,使得程序的主线保证相对完整,同时增加了程序的可读性和可维护性。异常沿着调用层次向上抛出,交由调用它的方法来处理。

 

为什么要在方法中抛出异常?

系统自动抛出异常一般就能解决大部分问题,但有时候,程序会产生特定的要求,需要由用户自己定义异常信息,又或者联合开发程序模块时,不同程序员需要将各自负责代码部分尽量避免因程序出错影响其他人的编码,都需要显式抛出异常,以便程序进行处理。这时候就需要在方法中抛出异常。

 

异常抛出的语法:

 throw  new  异常类( );

其中异常类必须Throwable类及其子类。


throws子句的方法声明的一般格式如下:

<类型说明> 方法名(参数列表) throws  <异常类型列表>

{

  方法体;

}

 

举例:

class ThrowException{
         // throwOne方法后用throws声明异常类ArithmeticException
  static void throwOne(int i) throws ArithmeticException {
    if(i==0)
      throw  new  ArithmeticException("i值为零");  //用throw抛出一个异常
  }
public static void main(String  args[]){
     //捕获异常
try{
      throwOne(0);
      }
   catch(ArithmeticException e){
             System.out.println("已捕获到异常错误: "+e.getMessage());
   }
  } 
}

程序执行结果:已捕获到异常错误: i值为零

四、自定义异常

用户自定义的异常类,只需继承一个已有的异常类就可以了,包括继承Execption类及其子类,或者继承已自定义好的异常类。如果没有特别说明,可以直接用Execption类作为父类。

   自定义类的格式如下:

class   异常类名 extends  Exception

{

  ……

}

n  自定义异常类必须继承自Throwable或Exception类,建议用Exception类。一般不把自定义异常作为Error的子类,因为Error通常被用来表示系统内部的严重故障。

n  当自定义异常是从RuntimeException及其子类继承而来时,该自定义异常是运行时异常,程序中可以不捕获和处理它。

n   当自定义异常是从Throwable、Exception及其子类继承而来时,该自定义异常是编译时异常,也即程序中必须捕获并处理它。

使用自定义异常的步骤如下:

l  首先通过继承java.lang.Exception类声明自定义的异常类。

l  在方法的声明部分用throws语句声明该方法可能抛出的异常。

l  在方法体的适当位置创建自定义异常类的对象,并用throw语句将异常抛出。

l  调用该方法时对可能产生的异常进行捕获,并处理异常。

//NewException.java
class NumberRangeException extends Exception{
     public NumberRangeException(String msg){
           super(msg);
     }
 
//throws重新抛出异常NumberRangeException
         public int CalcAnswer(String str1,String str2) throws NumberRangeException{
                    int int1, int2;
                    int answer = -1;
                    try {   
                             int1 = Integer.parseInt(str1); //可能产生异常对象NumberFormatException e
                             int2 = Integer.parseInt(str2); //可能产生异常对象NumberFormatException e
                              if( (int1 < 10) || (int1 > 20) || (int2< 10) || (int2 > 20) ){ 
                                       NumberRangeException e = new NumberRangeException("Numbersare not within the specified range.");
                                      throw e; //抛出自定义异常对象NumberRangeExceptione
                              }
                              answer = int1 + int2;
                    }
                   catch (NumberFormatExceptione){   //捕获异常对象NumberRangeException e
                              System.out.println( e.toString() );
                    }
                    return answer;
   }
//在调用方法getAnswer中捕获异常
   public void getAnswer(){
                   String answerStr;
                   try{
                            //将num1、num2的中的数字更改为小于10或大于20,以查看捕获异常结果。
                            Stringnum1="13";
                            Stringnum2="12";
                      int answer = CalcAnswer(num1, num2); //抛出异常对象NumberRangeException e
                      answerStr = String.valueOf(answer);
                   }
                   catch (NumberRangeExceptione){        //捕获异常对象NumberRangeException e
                      answerStr = e.getMessage();
                   }
                   System.out.println(answerStr);
   }
  
   public static void main(String args[]) {
     NumberRangeException t1=new NumberRangeException("test");
     t1.getAnswer();
  }

猜你喜欢

转载自blog.csdn.net/weixin_39407066/article/details/80919810