编程练习生的19天 《反射详解》

反射介绍

  • 反射是发生在程序运行期间的行为

  • 在以后的框架或技术的底层大量使用到了反射技术,使用代码变得更灵活,更简单
    */

  • 反射:

  • 1.创建对象这个类型的Class对象的一个镜像|复制体

  • 2.类加载到内存的时候,就在内存中存在的,不用我们手动创建就已经存在,并且只一个类只有一个表示这个类的Class对象

  • 3.你能拿到一个类型的Class对象,能够使用Class类中的这些成员方法操作这个类型

  • Class 类的实例表示正在运行的 Java 应用程序中的类和接口。

  • Java 反射机制,可以实现以下功能:
    ①在运行时判断任意一个对象所属的类;
    ②在运行时构造任意一个类的对象;
    ③在运行时判断任意一个类所具有的成员变量和方法;
    ④在运行时调用任意一个对象的方法;
    ⑤生成动态代理。
    获取类的 class 对象,也有三种方式:
    ①Class.forName(”包名.类名”)//一般尽量采用该形式
    ②类.class
    ③对象.getClass()

  Class c1 = Class.forName("class0719.Student");      // class.forName(包名.类名)
  Class c2 =Student.class;                             // 类名.class
  Class c3 =new Student().getClass();                 // 对象.getClass
  System.out.println(c1==c2);
  System.out.println(c1==c3);
  System.out.println(c1);      

运行结果

true
true
class class0719.Student

推荐使用第一种方式-----------划重点

一些方法
直接上代码

  String s=c1.getName();        // getName() 获取该类的名字 
  System.out.println(s);               
  System.out.println(c1.toString());  // 字符串的方式输出该类的名字
  System.out.println("============");
  System.out.println(Arrays.toString(c1.getClasses()));      // getClasses()获取该类以及他父类的所有公共的内部类
  System.out.println(Arrays.toString(c1.getInterfaces()));   //getInterfaces() 确定此对象所表示的类或接口实现的接口。 
  System.out.println(c1.getModifiers());                     // getModifiers()返回此类或接口以整数编码的 Java 语言修饰符
  System.out.println(Modifier.toString(c1.getModifiers()));  // Modifier.toString 将该类返回的语言修饰符转换成字符串形式
  System.out.println("============");

结果

class0719.Student
class class0719.Student
============
[class class0719.Student$ZZZ]
[interface class0719.StudentStudy]
1
public

一些应用

用来操作普通方法

  • Method getMethod(String name, Class<?>… parameterTypes)
    返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
    Method[] getMethods()
  • Method getDeclaredMethod(String name, Class<?>… parameterTypes)
    返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
    Method[] getDeclaredMethods()

执行方法
Object invoke(Object obj, Object… args) 参数1:调用方法的对象 参数2:方法的实参 返回值:执行方法的返回值
*/

下面直接上代码

  Method[] arr=cls.getMethods();        // 返回一个 Method返回一个数组,其中包含 它反映此 Class 对象所表示的类或接口的指定公共成员方法。 
  cls.newInstance();            //        创建一个新的这个 类对象所表示的类的实例。 
  System.out.println(Arrays.toString(arr));      // 
  System.out.println("============");
  
  // 获取某个指定的方法
  @SuppressWarnings("unchecked")
  ///getDeclaredMethod(方法名,参数的数据类型的Class对象列表)
  Method method1 = cls.getDeclaredMethod("Studya",String.class);      //  返回一个 方法指定对象,反映了声明的方法这个 类对象所表示的类或接口。 
  Student cs=(Student) cls.newInstance();             //创建一个新的这个 类对象所表示的类的实例。 类被实例化,好像 new表达式用一个空参数列表。
  method1.invoke(cs, "吴亦凡");               //调用底层方法由这个 方法对象,指定对象的指定参数 obj——调用对象的方法  args——用于方法调用的参数 
  System.out.println("============");
  //获取私有的方法
  Method method2=cls.getDeclaredMethod("play",String.class);
  
  Student cs1=(Student) cls.newInstance();//创建一个新的这个 类对象所表示的类的实例。 类被实例化,好像 new表达式用一个空参数列表。
  //setAccessible()        // 设置这个方法的访问类型
  method2.setAccessible(true);       // 为这个对象设置 accessible标志指定的布尔值。值 true表明反射的对象应该抑制Java语言访问检查时使用。值 false表明反射的对象应执行Java语言访问检查。 
  method2.invoke(cs1, "蔡徐坤");   
   
上结果
============
吴亦凡努力rap
============
蔡徐坤打篮球

获取构造方法

  • 1.获取
    一个类型的构造器
  • Constructor getConstructor(Class<?>… parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
    Constructor<?>[] getConstructors() 返回所有的公共的构造器
    通过构造器创建对象
    1.Class类中newInstance() 创建对象–>空构造
    2.Constructor类的成员方法 T newInstance(Object… initargs) ,接收匹配构造器的实参创建一个对象
    3.Constructor getDeclaredConstructor(Class<?>… parameterTypes 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
    4.Constructor<?>[] getDeclaredConstructors() 获取所有的构造器对象,包括私有的
    */

还是上代码


  public static void testConstructor(Class cls) throws Exception{
   Student cs=(Student) cls.newInstance();
   System.out.println(cs);
   System.out.println("============");
   
   公共的 带参构造  返回一个 Constructor指定对象,反映了公共类的构造函数由这个 类对象表示。  parameterTypes——参数数组
   // 结果  ---公众的 Constructor对象 parameterTypes指定匹配的构造函数   
   Constructor con = cls.getConstructor(String.class,int.class,boolean.class);
   //con表示匹配的构造方法
   Student st=(Student) con.newInstance("杨幂",19,true);     //通过指定构造器公共的创建对象 
   System.out.println(st);
   System.out.println("============");
   //Constructor<?>[] getConstructors() 返回所有的公共的构造器   
   Constructor[] con1 =  cls.getConstructors();
   System.out.println(Arrays.toString(con1));
   System.out.println("============");
   Student st1=(Student) con1[0].newInstance("宋慧乔",23,true);     //通过指定构造器公共的创建对象 
   System.out.println(st1);
   System.out.println("============"); 
   //Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes  
   //返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 
   Constructor con2 =  cls.getDeclaredConstructor(String.class);
   //为这个对象设置 accessible标志指定的布尔值。值 true表明反射的对象应该抑制Java语言访问检查时使用。值 false表明反射的对象应执行Java语言访问检查。 //
   //为这个对象访问权限
   con2.setAccessible(true);
   Student st2=(Student) con2.newInstance("呵呵哒");
   System.out.println(st2);
   con2.setAccessible(false);
   System.out.println("============");
   

还是上结果

Student [name=null, age=0, sex=false]
============
Student [name=杨幂,/ age=19, sex=true]
============
[public class0719.Student(java.lang.String,int,boolean), public class0719.Student()]   
============
Student [name=宋慧乔, age=23, sex=true]
============
Student [name=呵呵哒, age=0, sex=false]
============
利用反射创建对象与new对象稍有不同
1.反射会先拿到Student的“类对象”,然后通过类对象获取“构造器对象”再通过构造器对象创建一个对象,具体步骤:
Class cls = Class.fromName("class0719.Student");  //  获取类对象
Constructor con = cls.getConstructor(形参.class);     // 获取构造器对象
Student st =(这里需要强制类型转换)con.newInstance(实参);

// 获取字段 
   Field f1= cls.getDeclaredField("name");
   
   System.out.println(st2.name);
结果当然是:呵呵哒
													2019.07.19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值