反射、获取类对象的三种方式、类类、常见的异常、反射的三大作用

1、反射

 概念:反射是java语言的一种机制,通过这种机制,可以动态实例化对象、读取属性、调用方法

2、获取类对象的三种方式:

  a、Class.forName("完整的类名");

  b、类.class();

  c、类对象.getClass();

 注:一切与反射相关的代码都是从获得类对象开始的。

3、类类

  概念:所有的类都放在一起    泛指

  例如:所有狗    狗类  Dog (泛指)    狗对象 (特指)

            所有猫     猫类  Cat  (泛指)    猫对象(特指)

            所有类     类类   java.lang.Class   泛指   类对象(特指)

4、常见的异常:

   1、java.lang.ClassNotFoundExecption            类找不到异常

         出现的原因:1、类名错误     2、忘记导入jar包

  2、java.lang.NoSuchMethodExecption             找不到方法异常

       出现的原因:没有写这个方法

  3、java.lang.IllegalArgumentException            不合法的参数异常

      出现的原因:上文中带了参数  而下文要使用的地方没有带参数

5、反射的三大作用:

     1、实例化对象:

      例如:

//传统方式实例化对象
 
Student  stu=new Student();

 传统方式和反射机制实例化对象的区别:

    前者只能写固定的,就像上面的截图所示,只能实例化Student;

    而后者传完整的类名进去,可以实例化你所需要实例化的,不是固定的,因而更加方便,也可以简化代码

 反射实例化对象有无参和有参数的方法:

   1、无参数的方法   使用类对象.newInstance( );

//反射机制实例化对象

 Class  c1=Class.forName("com.zking.Student");

//这里使用object接收  也就是对象
  
 Student stu=(Student)c1.newInstance();

 System.out.println("stu");

2、有参数的方法  使用类对象.getConstructor(数据类型.class);

Class  c2=c1.getConStructor(String.class,String.class);

Student stu3=(Student) c2.newInstance("s007","LYF");

System.out.println(stu3);

注意:因为上文带了两个String类型的两个参数,那么 下文也要带上两个String类型的两个参数,否则会报下面这个错误.

Constructor c2=c1.getConstructor(String.class,String.class);

	Student stu3=(Student) c2.newInstance(); 

	System.out.println(stu3);

解析:这样子的代码就是有问题的,因为c2.newInstance的括号里面缺少两个String类型的参数;

报错如下图所示:

而图中的这个java.lang.IllegalArgumentExecption呢,就是上文中我写的常见的异常之一,

不合法的参数异常,而出现这个异常的原因无非是两种:

1是缺少对应的参数    2是上下文中的参数类型不匹配

OK,现在展示一下正确的代码截图:

2、动态的调用方法:         

      这里调用的方法也有两种,一种是私有的,一种是公开的;     

      1、公开的方法:  类对象.getMethod("方法名",可变参数(数组,参数));

     //相关代码

    Student s=new Student();

    s.setSname("WULI峰峰");

    System.out.println(s);
		
    //反射机制实例化对象

   Class c1=Class.forName("com.zking.Student");

   Method method=c1.getMethod("hello", new Class[]{String.class});

   method.invoke(s, "小汪同学");

接下来给你们看一下结果!!

2、私有的方法类对象.getDeclaredMethod("方法名",可变参数);

                           method.invoke(对象,“参数值”);

Method method2=c1.getDeclaredMethod("add", Integer.class,Integer.class);

method2.setAccessible(true);

Integer  n=(Integer)method2.invoke(s, 24,35);

System.out.println(n);

结果会输出59,因为是调用了一个add的方法

3、读取属性:

    1、公开的:类对象.getField();

Student s=new Student();

System.out.println(s);
	
//反射机制实例化对象

Class c1=Class.forName("com.zking.Student");

//获取类对象的属性

Field  agefield=c1.getField("age");  

//给类对象的属性赋值

agefield.set(s, 18);

//得到类对象的值

Integer age=(Integer)agefield.get(s);

System.out.println(age);

  输出的结果如下图所示:

:2、私有的方法类对象.getDeclaredField( );

Field sid=c1.getDeclaredField("sid");

sid.setAccessible(true);//开放权限

sid.set(s, "s009");

Object obj=sid.get(s);

System.out.println(obj);

 解析:setAccessible(true);//放开权限或者说是公开权限的意思;

如果缺少这一步的话,会报java.lang.IllegalAccessException这个异常,

就像下图所示这样:

是因为没有授权,所以这一步至关重要!

那么我们现在来看看正确的代码运行之后的结果!!!

3、set/get方法

补充知识点:访问修饰符:getModifiers();

作用:以二进制的方式将修饰符的二进制进行相加。

好啦,今天的总结就到这里,学海无涯,有什么问题或者建议欢迎私信或者评论交流噢!!!


版权声明:本文为qq_45464930原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。