zoukankan      html  css  js  c++  java
  • java基础反射!

    java反射

    反射:一句话来说就是把JAVA中的每一个成分解析在为相应的JAVA类。对java中的每一个成分都解析成一个类。

    1. Class类

       Class类代表JAVA类,它的实例对应实例在内存中的字节码。每个类被加载到内存中,都会被解析成字节码。

       那么Class的实例就表示这份字节码。

       得到Class实例对象的方法:

      1)直接类名调用:  Person.class;

      2)对象调用:  new Person().getClass();

      3)从内存中加载: Class.forName("java.lang.String");

    2.java反射的三个重要类:

       1)Constructor类:代表类中的一个构造方法。

    	Constructor<String> constructor = String.class.getConstructor(String.class);	//只取得公有方法。
    	//获取构造方法,传入一个参数,并且参数为String类型的构造方法
    	String string = (String)constructor.newInstance(new String("abc"));
    	//通过构造方法反射实例化对象。传入的参数必须是和获取的构造方法中取得的参数是一样的。

       2)Method:代表类中的一个方法。以下代码为反射成员方法:

    	System.out.println("----------------反射成員方法-------------------------");
    	methodCharAt = String.class.getMethod("charAt", int.class);
    
    	String str1 = "abc";
    
    	// 下面的invoke则要首先指定是哪个对象去调用上面指定的方法,后面一个则是传入的参数。
    	System.out.println(methodCharAt.invoke(str1, 1));
    	// methodCharAt.invoke(null,1); //这样则是表示静态方法调用。

    注意: 而这里的反射main方法则是需要对main方法中的参数进行包装。因为jdk1.5为了兼容jdk以前的版本。会对传入的数据进行拆分成单个对象。

    System.out.println("----------------反射main方法-------------------------");
    			
    			
    	Method mainMethod = Class.forName("com.test.Person").getMethod("main", String[].class);
    			
    	//System.out.println("main方法反射的错误传参方式。");
    	//mainMethod.invoke(null,new String[]{"ab","abc"});
    	/**
    	 * 异常:wrong number of arguments
    	 * **/
    			
    	/**
    	 * jdk1.5为了兼容jdk1.4,在传入一个Object类型的数组(String 直接继承Object),invoke给自动的进行拆开
    	 * 其中的每一个元素作为一个参数。这样就会导致了参数个数的不匹配。
    	 * 可能是因为,jdk1.5是支持可变参数的,但是在1.5以前是不支持可变参数的。
    	 * 
    	 * ***/
    			
    	System.out.println("main方法反射的第一种传参方式。");
    			
    	//这里就将数组再次的去打包成一个包,这样被拆开的时候还一个数组。
    	mainMethod.invoke(null,(Object)new String[]{"ab","abc"});
    	System.out.println("main方法反射的第二种传参方式。");
    	//这里强制转换成一个Object ,目的只是去骗过编译器,
    	//这样编译器不会去进行拆分操作。传入的依旧是一个数组。
    	mainMethod.invoke(null,new  Object[]{new String[]{"ab","abc"}});
    

    3)代表类中一个字段.

    	Field fieldX = pt1.getClass().getDeclaredField("x");
    

    如果为私用变量则不能够进行输出,那么就可以去进行暴力反射:

    	fieldX.setAccessible(true);

    3.反射的作用:

    1)实现动态代理

    2)实现框架

  • 相关阅读:
    Arduino Nano与SIM800C 通信
    Laravel 查询数据按照时间分组
    Laravel 查询或写入Enum字段出错的bug解决办法
    【示例代码及地区json】js省市区三级联动 升级版
    【示例代码及地区json】js省市区三级联动
    Laravel使用whereHas进行过滤不符合条件的预加载with数据
    Laravel where条件拼接,数组拼接where条件
    postman传数组参数,二维数组,多维数组
    中国元器件电商
    蓝牙核心技术了解(蓝牙协议、架构、硬件和软件笔记)
  • 原文地址:https://www.cnblogs.com/yangzhi/p/3576607.html
Copyright © 2011-2022 走看看