一、异常
1.异常结构
(1)异常
- 运行时异常:运行时出现的异常(例如运行时会出现数组下标越界异常和空指针异常)
int[] arr ={13,24,354};
arr[5]=100;//虽然代码有问题,不会影响到程序的执行,当执行时,进行异常的打印
String s = null;
s.toCharArray();// 程序运行时时,出现的异常,不会影响到程序的执行
- 非运行时异常:还没运行,出现了异常
(2)error:错误,不能解决
递归调用:自己的方法调用自己
===》栈溢出:StackOverflowError
2.异常处理
解决异常不是将代码改对,而是没有红色波浪线了
(1)异常处理方式一
- 捕获异常对象(异常是对象):catch捕获
- 如果try中的代码发生异常,产生一个异常对象,被catch进行捕获
- catch(ParseException e)捕获后,给ParseException类型的对象e进行赋值并打印异常轨迹catch(Throwable e):Throwable类是Java中所有错误和异常的父类,有两个子类:Error和Exception
如果运行时发生异常不想进行异常轨迹进行打印,那么可以自己设置输出对象
(2)异常处理方式二:抛出异常声明
1·抛出自定义异常:
自己定义一个异常继承Exception
2·异常对象来源:在方法的定义时就会抛出异常对象,当调用方法发生异常时,异常对象被创建出来。异常对象是手动创建出来的,这样可以在不同的情况下进行异常对象的创建
public class MyException extends Exception {
@Override
public void printStackTrace() {
System.out.println("异常轨迹打印的方法");
}
}
public class Test7 {
public static void test1() throws MyException {
System.out.println("test1.............");
throw new MyException();// 抛出异常对象
}
public static void main(String[] args) {
try {
test1();
} catch (MyException e) {
e.printStackTrace();
}
}
}
(3)try后面可以放多个catch,catch进行异常捕获时
- 如果异常的类型没有继承关系,异常捕获的顺序任意
- 但如果有继承关系,必须子类异常在上,父类异常在下
3.异常分类
- 运行时异常
- 编译时异常
面试:
1.遇到过什么异常
2.final和finaly的区别:
- final是一个关键词,修饰类和变量
- fianlly是和try{}catch同时使用的代码块,需要放到catch之后,不管异常是否发生,都会执行的一个代码块
3.throw和throws的区别:
- throws放在方法声明处,进行异常类型的标识,抛出异常声明
- throws放在方法体里面,进行抛出异常对象
二、反射
1.注解的注解===》元注解
@Target(ElementType.TYPE):加在类上
@Target(ElementType.MEATHOD):加在方法上
@Target(ElementType.TYPE,ElementType.MEATHOD):加在类上和方法上
@Target(ElementType.FIELD):加在属性上
@Retention(RetentionPolicy.RUNTIME):运行时生效
自定义注解时需要在类上方进行元注解的定义,上面一个类型只能写一个,就是Target只能写一个,不能写多个
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyT1 {
String name() default "abcd";// 定义注解时,注解中方法如何使用
// 使用注解,是注解中的参数
String t1() default "1234" ;
String value() default "va";// 默认的名字,进行一个参数书写时,不写参数名的赋值
//只有value在类中的注解里可以不写名字,其他属性都得先写属性名再写值
}
2.获取class对象的方式
- 通过class静态方法获取
try {
Class aClass = Class.forName("com.neuedu.test4.Dog");//必须把每一级包都写出来
System.out.println(aClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
-
通过类.Class
Class c = Dog.class;
System.out.println(c);
-
创建对象.getClass()
Class aClass = new Dog().getClass();
System.out.println(aClass);
3.通过对象调用方法获取类的各种属性
Class clz = Dog.class;//打印结果是class com.neuedu.test4.Dog
System.out.println(clz.getName());//输出结果是:com.neuedu.test4.Dog
System.out.println(clz.getPackage());//输出结果是:package com.neuedu.test4
System.out.println(clz.getSimpleName());//输出的结果是:Dog
System.out.println(clz.getSuperclass());//查看父类结果是:class java.lang.Object
System.out.println(Arrays.toString(clz.getInterfaces()));//获取对象所在类实现的接口
private修饰的属性,只能在当前类中使用
此方法不能进行私有属性的获取
Field[] fields = clz.getFields();
for (Field f:fields
) {
System.out.println(f);
}
try {
Field name = clz.getField("name");
System.out.println(name);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
跳过访问权限修饰符进行属性的访问
Field[] declaredFields = clz.getDeclaredFields();//获取类中的属性
for (Field f:declaredFields
) {
System.out.println(f);
}
try {
Field name = clz.getDeclaredField("name");//获取类中的name属性