java 获取反射异常信息_Java 异常与反射 总结

1.异常

异常,简单来说,就是一个程序执行过程中发生的不正常情况的事件。它发生在程序的运行期间,干扰了正常的指令流程。如果没有处理异常,那么出现异常之后,程序会停止运行。异常分为运行异常和非运行异常。非运行异常也叫编译异常。对于编译异常编译器要求必须处理。否则无法运行。运行时异常编译器不要求强制处理。运行时异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。它们都继承于Exception类。运行异常和非运行异常也下分各类异常。异常发生的原因是程序错误或偶然的外在因素导致的一般性问题。

继承关系如图

105be9f109d38f01216c33f8aa4ca804.png

如果一个方法内抛出异常,该异常会被抛到调用方法中。如果异常没有在调用方法中处理,它继续被抛给这个方法的调用者。这个过程将一直继续下去,直到异常被处理。这一过程称为捕获异常。

2.反射

在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射的思维导图如下

7b7499a27d03aff1d30457cd79706d04.png

当使用反射时候,首先需要获取到Class类的对象,得到了这个类之后,就可以得到class文件里面的所有内容。

以下是具体的反射应用方式

1.类型转换:将Map转成Person的示范

Person类是一个普通的实体类,里面包含三个私有的成员属性及它们的Set和Get函数。Map是集合框架里使用的Map类型框架,里面可以加入泛型。具体转换代码如下

1 //param1:要转化的数据类型Person.class String.class

2 public static Object toBean(Class> type,Map map) throwsException{3

4 //Introspector专门处理Bean的工具类。比如获取Class的属性或者方法或构造

5 BeanInfo beanInfo = Introspector.getBeanInfo(type);//参数传递的就是类的类型6 //调用newInstance方法创建这个类

7 Object o =type.newInstance();8 //获取o的方法

9 PropertyDescriptor[] ps =beanInfo.getPropertyDescriptors();10 for (int i = 0; i < ps.length; i++) {11

12 PropertyDescriptor p =ps[i];13 //获取方法描述的名称(属性名称)如果是Person --->name(name,age,sex)

14 String name =p.getName();15 //name是否就是map中的key?

16 if(map.containsKey(name)){17 //通过key获取map的值

18 Object value =map.get(name);19 //通过反射,value赋给o20 //p.getWriteMethod();//set方法21 //p.getReadMethod();//get方法

22 p.getWriteMethod().invoke(o, value);23 }24 }25 //获取map中的key的值,以及value的值

26 returno;27 }28 public static void main(String[] args) throwsException {29 Map pMap = newHashMap();30 pMap.put("name", "张三");31 pMap.put("age", 1);32 pMap.put("sex", 2);33 //Map--->Object

34 Person p = new Person("张三");35 p.setAge(1);36 p.setSex(2);37 Person o = (Person)toBean(Person.class,pMap);38 System.out.println(" "+o.toString());39 }

以上代码的思想就是,创建一个相对于想要的类的BeanInfo,然后通过这个BeanInfo对象得到所有的属性名称(对应到Map里就是所有键值对的键),然后判断Map里是否有与获取的键名称同名的键,如果有的话就通过Map获取那个键的值,然后通过PropertyDescriptor对象获取需要的对象的set方法,将值赋值给相应的属性,最后返回相应的类型的对象。

2.Java中五种创建新对象的方法

1>直接用new调用该类的构造函数

new Person("张三");

2>使用class类中的newInstance方法创建对象,调用构造函数

1 public static void test1() throwsClassNotFoundException, InstantiationException, IllegalAccessException{2 //1、获取Class类的对象

3 Class c = Class.forName("com.Person");4 //2、通过Class类中的newInstance方法创建Person对象

5 Person p =(Person)c.newInstance();6 //3、检测一下

7 p.setName("张三");8 System.out.println(p.getName());9 }

3>使用class类型中的构造函数中的newInstance方法

public static void test2() throwsNoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{//1、获取Person类型

Constructor c = Person.class.getConstructor();//2、创建方法

Person p =(Person)c.newInstance();//3、检测

p.setName("张三");

System.out.println(p.getName());

}

4>通过clone方法创建。前提是需要在实体类里重写clone()方法

/***实体类

**/

public class Person implementsCloneable{privateString name;private intage;private intsex;

@Overrideprotected Person clone() throwsCloneNotSupportedException {

Person person= null;

person= (Person)super.clone();returnperson;

}

}/***功能类中clone功能函数

**/

public static voidtest3(){//需要重写clone方法,重写cloneable接口。非常特殊//在Person类里实现cloneable接口

Person p1 =new Person("王五");//调用clone方法创建一个新的对象p2

Person p2 = null;try{

p2=p1.clone();

}catch(CloneNotSupportedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(p1==p2);

}

5>序列化和反序列化的方法,通过这种方法可以将对象转换为字节序列的方式,把对象传输到另一台机器上。

3.通过反射获取方法和操作属性

1>通过反射获取方法

通过反射获取方法的方式是先申明一个Class对象,然后通过该对象的getDeclaredMethod方法创建Method对象,通过Method对象的invoke方法调用获取到的方法实现功能。具体示例代码如下

1 public static voidtest5() {2 try{3 Class c = Class.forName("com.hpe.ref.Person");4 //获取方法 Person setName getName5 //param1:方法名的String类型6 //param2:方法的参数类型

7 Method m = c.getDeclaredMethod("setName", String.class);8 //创建Object对象

9 Object obj =c.newInstance();10 //invoke调用方法(反射的方式调用方法)11 //param1:反射的类,param2:m方法的值

12 m.invoke(obj, "张三");13 //验证

14 Method gM =c.getDeclaredMethod("getName");15 System.out.println(gM.invoke(obj));16 } catch(Exception e) {17 //TODO Auto-generated catch block

18 e.printStackTrace();19 }20 }

2>通过反射获取属性

通过反射获取属性的方法是通过Class获取该对象的Class对象形式,之后通过Field以字符串的形式获取类中的属性,然后通过Field对象来操作该属性。具体代码如下。

public static voidtest4(){//通过反射,在运行阶段创建这个person对象

try{

Class c= Class.forName("com.hpe.ref.Person");

Field field= c.getDeclaredField("name");//通过字符串的形式获取类中的属性。

Field[] fs =c.getDeclaredFields();//设置对属性,如果是私有的,可以有权限访问

field.setAccessible(true);

Object o=c.newInstance();//set方法----操作属性的方式

field.set(o, "张三");

System.out.println(field.get(o));

}catch(ClassNotFoundException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(NoSuchFieldException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InstantiationException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

3.小注:分析下列代码功能

f885f2d8799a773eb5bd776dec957c61.png

这段代码的功能分析

public int indexOf(int ch)

返回指定字符第一次出现的字符串内的索引。 如果与值的字符ch在此表示的字符序列发生String第一事件发生之对象,则索引(在Unicode代码单元)被返回。

public StringBuffer insert(int offset, char c)

在此序列中插入char参数的字符串表示形式。

总体效果就好像第二个参数通过方法String.valueOf(char)转换为一个字符串,并且该字符串中的字符然后是inserted到指定的偏移量的这个字符序列。

offset参数必须大于或等于0 ,小于或等于该序列的length 。

所以它的功能是,以小数点为界,每往前数三位,就在str字符串里插入一个逗号。以达到计算数字的位数效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值