java异常分类及处理
概念:如果某个方法不能按照正常的途径完成任务,就可以通过另一种路径退出方法。在这种情况下会抛出一个封装了错误信息的对象。此时,这个方法会立刻退出,同时不返回任何值。另外,调用这个方法的其它代码也无法继续执行,异常处理机制会将代码执行交给异常处理器。
异常分类:Throwable是java语言中所有错误或异常的超类。下一层分为Error和Exception。 Error:Error类是指java运行时系统的内部错误和资源耗尽错误。应用程序不会抛出该类对象。如果出现了这样的错误,除了告知用户,剩下的就是尽力使程序安全的终止。 Exception:有两个分支,一个是运行时异常RuntimeException,一个是CheckedException。 RuntimeException:如NullPointerException、ClassCastException。一个是检查异常CheckedException,如I/O错误导致的IOException、SQLException。RuntimeException是那些可能在Java虚拟机正常运行期间抛出的异常的超类。如果出现RuntimeException,那么一定是程序员的错误。 检查异常CheckedException:一般是外部错误,这种异常都发生在编译阶段,Java编译器会强制程序去捕获此类异常,即会出现要求你把这段可能出现异常的程序进行try catch,该类异常一般包括几个方面:1、试图在文件尾部读取数据 2、试图打开一个错误格式的URL 3、试图根据给定的字符串查找class对象,而这个字符串表示的类并不存在。 异常的处理方式:遇到问题不进行具体处理,而是继续抛给调用者(throw,throws),抛出异常有三种形式,一是throw,一个throws,还有一种系统自动抛异常。
public static void main(String[] args){
String s = "abc";
if(s.equals("abc")){
throw new NumberFormatException();
}else{
System.out.prinln(s);
}
}
int div(int a,int b) throws Exception{
return a/b;
}
Throw和Throws的区别: 位置不同:throws用在函数上,后面跟的是异常类,可以跟多个。而throw用在函数内,后面跟的是异常对象。 功能不同:throws用来声明异常,让调用者只知道该功能可能出现的问题,可以给出预先的处理方式。throw抛出具体的问题对象,执行到throw,功能就已经结束了,跳转到调用者,并将具体的问题对象抛给调用者。也就是说throw语句独立存在时,下面不要定义其它语句,因为执行不到。 throws表示出现异常的一种可能性,并不一定会发生这些异常。throw则是抛出了异常,执行throw则一定抛出了某种异常对象。 两者都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用者处理。
java反射
动态语言:动态语言是指程序在运行时可以改变其结构。新的函数可以引进,已有的函数可以被删除等结构上的变化。比如常见的JavaScript就是动态语言,除此之外Ruby、Python等也属于动态语言,而C、C++则不属于动态语言。从反射角度说JAVA属于半动态语言。 反射机制概念(运行状态中直到类所有的属性和方法): 在java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法。并且对于任意一个对象,都能够调用它的任意一个方法。这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
反射的应用场合: 编译时类型和运行时类型:在java程序中许多对象在运行时都会出现两种类型:编译时类型和运行时类型。编译时的类型由声明对象时使用的类型来决定,运行时类型由实际赋值给对象的类型决定。如:Person p = new Student(); 其中编译时类型为Person ,运行时类型为Student。 编译时类型无法获取具体方法。程序在运行时还可能接收到外部传入的对象,该对象的编译时类型为Object,但是程序有需要调用该对象的运行时类型的方法。为了解决这些问题,程序需要在运行时发现对象和类的真实信息。然而,如果编译时根本无法阈值该对象和类属于那些类,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须使用到反射了。
java反射API:发射API用来生成JVM中的类、接口或者对象的信息。 1、Class类:反射的核心类,可以获取类的属性、方法等信息。 2、Field类:Java.lang.reflec包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。 3、Method类:Java.lang.reflec包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。 4、Constructor类:Java.lang.reflec包中的类,表示类的构造方法。
反射使用步骤(获取Class对象、调用对象方法): 1、获取想要操作的类的Class对象,它是反射的核心,通过Class对象我们可以任意调用类的方法。 2、调用Class类中的方法,即就是反射的使用阶段。 3、使用反射API来操作这些信息。
获取Class对象的3中方法: 1、调用某个对象的getClass()方法。
Person p = new Person();
Class clazz = p.getClass();
2、调用某个类的class属性来获取该类对应的Class对象。
Class clazz = Person.class;
3、使用Class类中的forName()静态方法(最安全、性能最好)
Class clazz = Class.forName("类的全路径");
当我们获得了想要操作的类的Class对象后,可以通过Class类中的方法获取并查看该类中的方法和属性。
Class clazz = Class.forName("reflection.Person");
Method [] method = clazz.getDeclaredMethods();
for(Method m:method){
System.out.println(m.toString());
}
Field [] field = clazz.getDeclaredFields();
for(Field f:field){
System.out.println(f.toString());
}
Constructor [] constructor = clazz.getDeclaredConstructors();
for(Constructor c:constructor){
System.out.println(c.toString());
}
创建对象的两种方法: 1、Class对象的newInstance():使用Class对象的newInstance()方法来创建该Class对象对应类的实例,但是这种方法要求该Class对象对应的类有默认的空构造器。 2、调用Constructor对象的newInstance():先使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建Class对象对应类的实例,通过这种方法可以选定构造方法创建实例。
Class clazz = Class.forName("reflection.Person");
Person p = (Person)clazz.newInstance();
Constructor c = clazz.getDeclaredConstructor(String.class,String.class,int.class);
Person p1 = (Person)c.newInstance("李四","男",20);
|