反射是什么?

  通俗理解 - 照X光。

  java:一个类在反射面前就像照X光,清清楚楚明明白白。

  应用:我们的ide中,能够"."一下就知道类中的所有方法就是通过反射实现的。

     XML中配置的class全路径动态生成类。(框架)

  程序在运行过程中,动态的创建对象。

    -- 只要知道类的名称,就可以利用他的字节码对象来创建该类的一个对象。

何为class对象:

  HelloWorld.java

  通过 javac HelloWorld.java   ----->HelloWorld.class(字节码文件) ---> java HelloWorld    jvm把HelloWorld.class加载到内存中,变成Class对象

  

关于Class的加载:

public static void main(String[] args) {
Person p = new Person();
Class pClassclass = p.getClass();
System.out.println(pClassclass);
Person person = new Person("aa", "18", "USA");
Class personClass = person.getClass();
System.out.println(personClass);
System.out.println(pClassclass == personClass); //true 字节码文件在程序运行过程中,只会被加载到内存中一次
}

  

获取Class的三种方法: p.getClass(),  Person.class,  Class.forName("类名全路径")

public static void main(String[] args) throws ClassNotFoundException {
Person p = new Person();
Class p1 = p.getClass();
Person person = new Person("aa", "18", "USA");
Class p2 = person.getClass();
System.out.println(p1 == p2);
Class<Person> p3 = Person.class;
System.out.println(p3 == p1);
Class<?> p4 = Class.forName("com.java.demo.clazz.Person");
System.out.println(p4 == p3);
}

无论是哪一种,字节码都只有一个

使用Class

  先看下类和字节码对象的关系

  

关于构造方法:

  方式一:用newInstance()方法

  class.newInstance(),时,newInstance()底层需要调用无参的构造方法,所以,我们被反射的类中,需要有一个无参的构造方法。

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
//通过字节码对象,创建一个对象
Class<?> aClass = Class.forName("com.java.demo.clazz.Person");
Person person = (Person) aClass.newInstance(); }

  方式二:用Constructor, 这个时候,空参的构造方法就是非必须的了。

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> aClass = Class.forName("com.java.demo.clazz.Person");
Constructor<?> constructor = aClass.getConstructor(String.class, String.class,String.class);
Person instance = (Person)constructor.newInstance("aa", "18", "USA");
}

  方式二的增强版:当用的是getDeclaredConstructor()方法,setAccessible(true)之后,就算他的构造方法是private的也能创建对象(他能获取到所有的东西,包括公共的私有的)

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> aClass = Class.forName("com.java.demo.clazz.Person");
Constructor<?> constructor = aClass.getDeclaredConstructor(String.class, String.class,String.class);
constructor.setAccessible(true); //暴力访问 IllegalAccessException
Person instance = (Person)constructor.newInstance("aa", "18", "USA");
}

获取Field(成员变量)

  只要是Declared的,就能获取到所有声明的变量

public static void main(String[] args) {
Class<Person> personClass = Person.class;
Field[] fields = personClass.getFields(); //这种只能获取到公共的
for (Field f : fields) {
System.out.println(f);
}
Field[] declaredFields = personClass.getDeclaredFields(); //这种可以获取到所有的
for (Field f : declaredFields) {
System.out.println(f);
}
}

获取Method(类中的方法)

  只要是Declared的,就能获取到所有声明的方法

 public static void main(String[] args) {
Class<Person> personClass = Person.class;
Method[] declaredMethods = personClass.getDeclaredMethods();
for (Method method : declaredMethods){
System.out.println(method);
}
}

  Method方法的调用

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
Class<Person> personClass = Person.class;
Person person = personClass.newInstance();
Method spark = personClass.getDeclaredMethod("spark",String.class);
//执行方法,invoke, 两个参数
//第一个参数method属于那个对象,第二个对象方法参数
spark.setAccessible(true);
spark.invoke(person,"HeLLO GRIL");
}

最新文章

  1. LoadRunner免费公开课,惠普金牌讲师亲授
  2. The Nine Indispensable Rules for HW/SW Debugging 软硬件调试之9条军规
  3. [CentOs7]iptables防火墙安装与设置
  4. yii 多模板
  5. 【转载】 Pyqt QStackedWidget堆栈窗体
  6. 1048 图的宽度优先遍历序列 c语言
  7. 关于offset()的理解
  8. c#调用钩子
  9. [转]IDENT_CURRENT、SCOPE_IDENTITY、@@IDENTITY 差異對照表
  10. JavaSE教程-04Java中循环语句for,while,do&#183;&#183;&#183;while
  11. docker~写个容器启动的bash脚本
  12. 人工智能技术实践篇:espeak开发环境调试
  13. React从入门到放弃之前奏(4):Redux中间件
  14. JDK--box和unbox
  15. nginx的配置与应用
  16. Mac 视频录制然后转 gif
  17. MVC架构介绍—查询功能的开发
  18. git创建版本库 小白操作 (看图)
  19. C语言、编程语言发展史
  20. 【转】每天一个linux命令(31): /etc/group文件详解

热门文章

  1. Gameia
  2. “打开ftp服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹&quot;
  3. python 03 8/25-8/27 range 、randint
  4. python基础——4(数字、字符串、列表类型的内置方法介绍)
  5. Selenium加载Chrome/Firefox浏览器配置文件
  6. 大数据学习——linux常用命令(五)
  7. Leetcode 300.最长上升子序列
  8. 【ITOO 5】启用MSDTC后的各种问题,以及解决方案
  9. linux rdesktop远程Win7老是提示密码错误问题解决
  10. 10.1——pair,map,set,multimap,multiset