• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

深入理解java反射

技术杂谈 勤劳的小蚂蚁 4个月前 (12-31) 77次浏览 已收录 0个评论 扫描二维码

一:什么是反射
反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。
简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
二:反射有哪些用途
很多人都认为反射在实际的Java开发应用中并不广泛,其实不然。
当我们在使用IDE(如Eclipse,IDEA)时,当我们输入一个对象或类并想调用它的属性或方法时,一按点号,编译器就会自动列出它的属性或方法,这里就会用到反射。
反射最重要的用途就是开发各种通用框架,很多框架(比如Spring)都是配置化的(比如通过XML文件配置JavaBean,Action之类的),为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射——运行时动态加载需要加载的对象。
举一个例子,在运用Struts 2框架的开发中我们一般会在struts.xml里去配置Action,比如:
class=“org.ScZyhSoft.test.action.SimpleLoginAction”
method=“execute”>
/shop/shop-index.jsp
login.jsp
配置文件与Action建立了一种映射关系,当View层发出请求时,请求会被StrutsPrepareAndExecuteFilter拦截,然后StrutsPrepareAndExecuteFilter会去动态地创建Action实例。
——比如我们请求login.action,那么StrutsPrepareAndExecuteFilter就会去解析struts.xml文件,检索action中name为login的Action,并根据class属性创建SimpleLoginAction实例,并用invoke方法来调用execute方法,这个过程离不开反射。
对与框架开发人员来说,反射虽小但作用非常大,它是各种容器实现的核心。而对于一般的开发者来说,不深入框架开发则用反射用的就会少一点,不过了解一下框架的底层机制有助于丰富自己的编程思想,也是很有益的。
三:反射的一些基本用法
1、获得Class对象
方法有三种
(1).方式一:
通过对象的getClass方法进行获取。
麻烦在于每次是不是都需要具体的类和该类的对象,以及调用getClass方法。
代码:
Public staticvoidmain(String[]args){
publicstaticvoidgetObject_1(){
 Person p=new Person();
         Class clazz=p.getClass();
Person p1=new Person();
Class clazz1=p1.getClass();
           }
}
(2).方式二:
任何数据类型都具备着一个静态的属性Class,这个属性直接获取到该类型的对应Class对象。
比第一种简单。不用创建对象,不用调用getClass方法。
但是还是需要使用具体的类,
代码:
publicstaticvoidgetObject_2(){
Class clazz=Person.Class;
}
(3).方式三:
这种方式较为简单,只要知道类的名称即可。
不需要通过该类,也不需要去调用具体的属性和行为。
就可以获取到Class对象。
这种仅知道类名就可以获取该类字节码对象的方式,更有利于扩展。
代码:
publicstaticvoidgetObject_3()throws ClassNotFoundException{
String className=“所属包+Person”
Class clzz=Class.forName(className);
}
2、判断是否为某个类的实例
用instanceof关键字来判断是否为某个类的实例。同时也可以借助反射中Class对象的isInstance()方法来判断是否为某个类的实例,它是一个Native方法:
publicnativebooleanisInstance(Object obj);
3、创建实例
通过反射来生成对象主要有两种方式。
(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。
(2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。
//获取String所对应的Class对象
Class c = String.class;
//获取String类带一个String参数的构造器
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance(“23333”);
System.out.println(obj);
4、获取方法
获取某个Class对象的方法集合,主要有以下几个方法:
public Method getMethod(String name, ClassparameterTypes)
举例说明一下:
package org.ScZyhSoft.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
publicclasstest1 {
publicstaticvoidtest() throws IllegalAccessException,
InstantiationException, NoSuchMethodException, InvocationTargetException {
Class c = methodClass.class;
Object object = c.newInstance();
Method[] methods = c.getMethods();
Method[] declaredMethods = c.getDeclaredMethods();
//获取methodClass类的add方法
Method method = c.getMethod(“add”, int.class, int.class);
//getMethods()方法获取的所有方法
System.out.println(“getMethods获取的方法:”);
for(Method m:methods)
System.out.println(m);
//getDeclaredMethods()方法获取的所有方法
System.out.println(“getDeclaredMethods获取的方法:”);
for(Method m:declaredMethods)
System.out.println(m);
}
}
classmethodClass {
public final int fuck = 3;
publicintadd(int a,int b) {
return a+b;
}
publicintsub(int a,int b) {
return a+b;
}
}
通过getMethods()获取的方法可以获取到父类的方法,比如java.lang.Object下定义的各个方法。
5、获取构造器信息
6、调用方法
当我们从类中获取了一个方法后,我们就可以用invoke()方法来调用这个方法。invoke方法的原型为:

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:深入理解java反射
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00