反射机制(java)

反射机制

反射机制可通过在运行时加载类名而获取类,并对其进行操作。工厂模式,动态代理中较常用到。

在实际场景中:由于有好多类具有共同的接口样式,而他们又用的不是很频繁,如果在服务器中保有这些类会占用资源空间,如果通过接口指定的方式去加载,用完之后就销毁掉,可节省资源空间,且实现接口编程,扩展性好,代码量也少。打个比方:哺乳动物Animal为接口,里面包括获取乳头数,获取腿,获取头,获取尾巴等,像这种都具有一定共性,实现类为老虎,狮子,兔子,羊等等等。

1.获取className,常用的形式将需要反射的类放在属性文件*.properties或数据库字段中,通过key获取类名及路径。

 1 private static final String CLASS_NAME_PATH = "pattern/classname.properties";
 2
 3     /**
 4      * 获取类名称
 5      * @return
 6      */
 7     private static String getClassName(String name) {
 8         Properties pro = new Properties();
 9         try {
10             String url = ProxyFactory.class.getClassLoader().getResource("").getPath() + CLASS_NAME_PATH;
11             pro.load(new FileInputStream(url));
12         } catch (FileNotFoundException e) {
13             e.printStackTrace();
14         } catch (IOException e) {
15             e.printStackTrace();
16         }
17         return (String)pro.get(name);
18     }

getClassName

1 # animal
2 lion = pattern.creation.factory.animal.Lion
3 sheep = pattern.creation.factory.animal.Sheep
4 rabit = pattern.creation.factory.animal.Rabit
5 # plant
6 apple = pattern.creation.factory.plant.Apple
7 pear = pattern.creation.factory.plant.Pear
8 plum = pattern.creation.factory.plant.Plum

classPath.properties

>>> String strClass = getClassName("rabit");//获取兔子类

2.获取类,创建类实例

Class<?> clazz = Class.forName(strClass);  //获取类

Object obj = clazz.newInstance();            //构建实例对象

Class<?> superClazz = clazz.getSuperclass(); //获取父类
Class<?>[] interfaceArray = clazz.getInterfaces();//获取接口

 1     /**
 2      * 根据classname获取类名
 3      * @param strName
 4      * @return
 5      * @throws ClassNotFoundException
 6      * @throws InstantiationException
 7      * @throws IllegalAccessException
 8      */
 9     @SuppressWarnings("unchecked")
10     public <T> T getClassByName(String strName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
11         String strClass = getClassName(strName);
12         Class<?> clazz = Class.forName(strClass);
13         Class<?> superClazz = clazz.getSuperclass();
14         Class<?>[] interfaceArray = clazz.getInterfaces();
15         System.out.println("className--: " + clazz.getName());//当前类名
16         System.out.println("superClassName--: " + superClazz.getName());//父类
17         for(Class<?> interfaces: interfaceArray){
18             System.out.println("interface--: " + interfaces.getName());//接口
19         }
20         return (T)clazz.newInstance();
21     }

getClass

>>> AnimalFactory animal = reflectFactory.getClassByName("rabit");

运行结果:

className--: pattern.creation.factory.animal.Rabit
superClassName--: pattern.creation.factory.animal.Animals
interface--: pattern.creation.factory.animal.AnimalFactory

3. 获取类属性及信息

Field[] fieldArray = clazz.getDeclaredFields(); // 显示所有的属性
Field[] publicFieldArray = clazz.getFields(); //显示public属性的元素

String name = field.getName();    //获取方法名

String modify = Modifier.toString(field.getModifiers());   // 修饰词
String classType = field.getType().getSimpleName();    // 类型
Annotation[] annoArray = field.getAnnotations();        // 注解

field.setAccessible(true);        //获取value要赋予权限

Object obj = clazz.newInstance();    //对象实例
Object value = field.get(obj);// 私有属性需要获取权限才可以

field.set(obj, value + "-----changed..");// 修改私有属性的值

 1     /**
 2      * 通过反射机制获取类 的属性名及其内容
 3      * @param strName
 4      * @throws ClassNotFoundException
 5      * @throws InstantiationException
 6      * @throws IllegalAccessException
 7      */
 8     public void getClassFieldByName(String strName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
 9         String strClass = getClassName(strName);
10         Class<?> clazz = Class.forName(strClass);
11         Object obj = clazz.newInstance();
12         Field[] fieldArray = clazz.getDeclaredFields(); // 显示所有的属性
13         Field[] publicFieldArray = clazz.getFields();  //显示public属性的元素
14         Field[] newFieldArray = (Field[])ArrayUtils.addAll(fieldArray, publicFieldArray);
15         for(Field field : newFieldArray){
16             String name = field.getName();
17             String modify = Modifier.toString(field.getModifiers());
18             String classType = field.getType().getSimpleName();
19             Annotation[] annoArray = field.getAnnotations();
20             String strAnno = "";
21             for(Annotation anno : annoArray){
22                 strAnno += "@"+anno.annotationType().getSimpleName();
23             }
24             field.setAccessible(true);
25             Object value = field.get(obj);// 私有属性需要获取权限才可以
26             System.out.println("propertyName:  " + strAnno + "  " + modify+ " " + classType + " " + name + "=" + value);
27             if(!StringUtils.contains(modify, "final")){
28                 field.set(obj, value + "-----changed..");// 修改私有属性的值
29                 System.out.println("propertyName:  " + strAnno + "  " + modify+ " " + classType + " " + name + "=" + value);
30             }
31         }
32
33         Field[] fieldsArray = clazz.getSuperclass().getDeclaredFields();//父类的属性名
34         for(Field field : fieldsArray){
35             String name = field.getName();
36             String modify = Modifier.toString(field.getModifiers());
37             String classType = field.getType().getSimpleName();
38             field.setAccessible(true);
39             Object value = field.get(obj);// 私有属性需要获取权限才可以
40             System.out.println("superPropertyName: " + modify+ " " + classType + " " + name + "=" + value);
41         }
42     }

getClassFieldByName

>>> reflectFactory.getClassFieldByName("rabit");

运行结果:

propertyName: private String rabitName=I am rabit
propertyName: private String rabitName=I am rabit
propertyName: private String header=
propertyName: private String header=
propertyName: private static final int LEGS=4
propertyName: @Resource public String tails=1tails
propertyName: @Resource public String tails=1tails
propertyName: @Resource public String tails=1tails-----changed..
propertyName: @Resource public String tails=1tails-----changed..
superPropertyName: private static final long serialVersionUID=8482086762730882629
superPropertyName: private int slegs=0
superPropertyName: private int shands=0
superPropertyName: private int sheader=0

4. 获取方法,及方法调用

String modifier = Modifier.toString(method.getModifiers()); //修饰词
String returnType = method.getReturnType().getSimpleName();//返回类型
String name = method.getName();//方法名
Parameter[] parameters = method.getParameters();//参数列表
Annotation[] annoArray = method.getAnnotations();//注解列表

Method method = clazz.getMethod(methodName, classes); //根据方法名,获取方法

method.invoke(obj, orgs); //方法调用

 1     /**
 2      * 获取方法并调用方法
 3      * @param strName
 4      * @param methodName
 5      * @param orgs
 6      * @param classes
 7      * @throws ClassNotFoundException
 8      * @throws InstantiationException
 9      * @throws IllegalAccessException
10      * @throws NoSuchMethodException
11      * @throws SecurityException
12      * @throws IllegalArgumentException
13      * @throws InvocationTargetException
14      */
15     public void getRunMethodByMethodName(String strName, String methodName, Object[] orgs, Class<?>[] classes) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
16         String strClass = getClassName(strName);
17         Class<?> clazz = Class.forName(strClass);
18         Class<?> superClazz = clazz.getSuperclass();
19         Object obj = clazz.newInstance();
20         Method[] methodArray = clazz.getDeclaredMethods();
21         Method[] supeMethodArray = superClazz.getDeclaredMethods();
22         Method[] sumMethodArray = (Method[])ArrayUtils.addAll(methodArray, supeMethodArray);
23         for(Method method : sumMethodArray){
24             String modifier = Modifier.toString(method.getModifiers());
25             String returnType = method.getReturnType().getSimpleName();
26             String name = method.getName();
27             Parameter[] parameters = method.getParameters();
28             Annotation[] annoArray = method.getAnnotations();
29             String strAnno = "";
30             for(Annotation anno : annoArray){
31                 strAnno += "@"+anno.annotationType().getSimpleName();
32             }
33             String strPara = "";
34             for(Parameter para : parameters){
35                 strPara+=para.getType().getSimpleName() + "  " + para.getName() + ",";
36             }
37             System.out.println("method:----"+strAnno + "  " + modifier + " " + returnType + " " + name + "(" + strPara +")");
38         }
39         Method method = clazz.getMethod(methodName, classes);
40         System.out.println("header:  " + method.invoke(obj, orgs));
41     }

getRunMethodByMethodName

>>> Class<?>[] classArray = {String.class,int.class,String.class};
>>> Object[] paramsArray = {"兔子只有",1,"头"};
>>> reflectFactory.getRunMethodByMethodName("rabit", "getHeader",paramsArray, classArray);

运行结果:

method:---- public String getHeader()
method:---- public String getHeader(String arg0,int arg1,String arg2,)
method:---- public int getLegs()
method:---- public int getLegs()

header:  兔子只有[email protected]@@@@@头

5. 构造体方法

clazz.getConstructors()  // 获取所有的构造体

----------------------------------------------------------------------------------------------------------

以上,为个人总结,如有写的不当之处,还望指正。

-----------DennyZhao

时间: 2024-11-09 01:35:29

反射机制(java)的相关文章

moon 反射机制---java.lang.reflect包

java反射机制:在运行状态中,对于一个已经加载到JVM的java对象/类 在程序中实现访问.检查.修改.描述java对象本身的信息(构造方法.方法.成员变量.类本身的信息) 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection, 反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接. 二,反射机制的作用:

反射机制(Java)

反射机制 今天闲来无事,对反射机制http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html阅读一番,整理了下这方面的知识以及自己的一些心得,希望对大家有帮助! JAVA反射机制是在运行状态中,可以动态的,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.换句话说就是:对于任意的类动态的获得该类的信息以及动态的调用对象

Java中的反射机制

Java反射的概念 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制 Java反射机制主要提供下面几种用途: 1.在运行时判断任意一个对象所属的类 2.在运行时构造任意一个类的对象 3.在运行时判断任意一个类所具有的成员变量和方法 4.在运行时调用任意一个对象的方法 首先看一个简单的例子,通过这个例子来理解Java的反射机制是如何工作的 i

java反射机制详解 及 Method.invoke解释 getMethod

JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理.1. 得到某个对象的属性 public Object getProperty(Obje

java反射机制详解 及 Method.invoke解释

JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理.1. 得到某个对象的属性 Java代码   public Object getProp

Java学习之:反射机制

一.反射机制应用场景 知道在哪里用的情况很重要,任何东西的产生都有他的来由,知道了场景才知道为什么要发明这个东西. 一般在开发针对java语言相关的开发工具和框架时使用,比如根据某个类的函数名字,然后执行函数,实现类的动态调用! 而且这么看,所有面向对象的语言可能都会用到这个机制,西草原生并不支持这种机制,但是可以手动实现,详情请见好基友的文章,http://blog.csdn.net/k346k346/article/details/51698184 二.反射机制 言归正传,来具体说说什么是反

java反射机制(2)

首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Reflection API JAVA反射机制提供了什么功能 获取类的Class对象 获取类的Fields 获取类的Method 获取类的Constructor 新建类的实例       Class<T>的函数newInstance       通过Constructor对象的方法newInstance 调

Java学习之反射机制

前段时间在做项目的时候,由于是用的纯Servlet基础框架进行开发的,没有用到那些集成的框架,后来在后台处理表单中的数据的时候,感觉有很多东西都是重复的,比较繁琐,例如获取到前台页面表单中的值之后,要在后台实例化一个对象并且调用定义的setter方法来给对象赋值,由于表单中的数据比较多,然后这个调用setter方法的代码就显得有些重复臃肿,后来网上查资料才了解到可以通过java中的反射机制简化这一操作,并且也知道了很多框架里面也都用到了反射... 一.什么是反射机制 JAVA反射机制是在运行状态

Java反射机制详解(1) -反射定义

---恢复内容开始--- 首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Reflection API JAVA反射机制提供了什么功能 获取类的Class对象 获取类的Fields 获取类的Method 获取类的Constructor 新建类的实例        Class<T>的函数newInstance        通过Constructor对象的

简谈Java 反射机制,动态代理

谈谈 Java 反射机制,动态代理是基于什么原理?小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:701136382 这是小编创建的java高阶学习交流群,加群一起交流学习深造.群里也有小编整理的2019年最新最全的java高阶学习资料! 反射机制 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力.可以在运行时通过提供完整的"包名+类名.class"得到某个对象的类型. 功能 在运行时能判断任意一个对象所属的