那么什么是Java的反射呢?
大家都知道,要让Java程序能够运行,那么就得让Java类要被Java虚拟机加载。Java类如果不被Java虚拟机加载,是不能正常运行的。现在我们运行的所有的程序都是在编译期的时候就已经知道了你所需要的那个类的已经被加载了。
Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类。这样的特点就是反射。
那么Java反射有什么作用呢?
假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。
Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。大家都用过Jcreator和eclipse。当我们构建出一个对象的时候,去调用该对象的方法和属性的时候。一按点,编译工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供用户进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审。
Class类
要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。
上半部分转自这里。
Class类的使用
面向对象,万事万物皆对象。
java语言中,两种不面向对象:静态的成员、普通数据类型类
静态的成员 | 属于类 |
普通数据类型 | 有包装类弥补 |
类是对象,类是java.lang.Class类的实例对象。
任何一个类都是Class的实力类。
Class类由java virtual machine虚拟机创建。
Class类获取的实例对象表示了实例类的类类型(Class type)
Class类动态加载类的使用
动态加载:运行时刻加载类 Class.forName("类的名称"); 优点:用的时候调用不影响程序运行。
静态记载:编译时刻加载类 new创建对象是静态加载类。
用动态加载的方法实例化多个相似类,可以创建一个接口,让这些相似类实现这个接口,只创建这个接口类的对象即可。
使用Class.forName( )静态方法的目的是为了动态加载类。在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。因此,单单使用Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。 详见java中newInstance()和new()的区别
Java获取方法信息
方法的反射
方法反射的操作:method.invoke(对象,参数列表) 当然前提是获取到方法。
1.获取类的信息首先要获得类的类类型 获取class对象。 A a = new A(); Class c = a.getClass();
2.方法获取:名称和参数来决定 getMethod获取public方法 getDelcaredMethod自己声明的方法
Method m=c.getMethod("方法名",参数列表);
方法的反射操作是用m对象来进行方法调用的 本来有a1.print(参数列表);可以进行调用。方法的反射和这个调用的效果完全相同
通过Class,Method来认识泛型的本质
Java中集合的泛型,是防止错误输入,只在编译阶段有效,绕过编译就无效了。。。例如创建一个String泛型的ArrayList,当向其中添加其他类型数 据时会提示错误。
可以通过方法的反射绕过编译添加数据
ArrayList<String> list = new ArrayList<String>();
Class c=list.getClass();
Method m=c.getMethod("add",Object.class);
m.invoke(list,参数数据);
但结果是不能用for-each进行遍历不然抛异常类型转换错误