反射机制

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

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

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

 private static final String CLASS_NAME_PATH = "pattern/classname.properties";

     /**
* 获取类名称
* @return
*/
private static String getClassName(String name) {
Properties pro = new Properties();
try {
String url = ProxyFactory.class.getClassLoader().getResource("").getPath() + CLASS_NAME_PATH;
pro.load(new FileInputStream(url));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return (String)pro.get(name);
}

getClassName

 # animal
lion = pattern.creation.factory.animal.Lion
sheep = pattern.creation.factory.animal.Sheep
rabit = pattern.creation.factory.animal.Rabit
# plant
apple = pattern.creation.factory.plant.Apple
pear = pattern.creation.factory.plant.Pear
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();//获取接口

     /**
* 根据classname获取类名
* @param strName
* @return
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
*/
@SuppressWarnings("unchecked")
public <T> T getClassByName(String strName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String strClass = getClassName(strName);
Class<?> clazz = Class.forName(strClass);
Class<?> superClazz = clazz.getSuperclass();
Class<?>[] interfaceArray = clazz.getInterfaces();
System.out.println("className--: " + clazz.getName());//当前类名
System.out.println("superClassName--: " + superClazz.getName());//父类
for(Class<?> interfaces: interfaceArray){
System.out.println("interface--: " + interfaces.getName());//接口
}
return (T)clazz.newInstance();
}

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..");// 修改私有属性的值

     /**
* 通过反射机制获取类 的属性名及其内容
* @param strName
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public void getClassFieldByName(String strName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String strClass = getClassName(strName);
Class<?> clazz = Class.forName(strClass);
Object obj = clazz.newInstance();
Field[] fieldArray = clazz.getDeclaredFields(); // 显示所有的属性
Field[] publicFieldArray = clazz.getFields(); //显示public属性的元素
Field[] newFieldArray = (Field[])ArrayUtils.addAll(fieldArray, publicFieldArray);
for(Field field : newFieldArray){
String name = field.getName();
String modify = Modifier.toString(field.getModifiers());
String classType = field.getType().getSimpleName();
Annotation[] annoArray = field.getAnnotations();
String strAnno = "";
for(Annotation anno : annoArray){
strAnno += "@"+anno.annotationType().getSimpleName();
}
field.setAccessible(true);
Object value = field.get(obj);// 私有属性需要获取权限才可以
System.out.println("propertyName: " + strAnno + " " + modify+ " " + classType + " " + name + "=" + value);
if(!StringUtils.contains(modify, "final")){
field.set(obj, value + "-----changed..");// 修改私有属性的值
System.out.println("propertyName: " + strAnno + " " + modify+ " " + classType + " " + name + "=" + value);
}
} Field[] fieldsArray = clazz.getSuperclass().getDeclaredFields();//父类的属性名
for(Field field : fieldsArray){
String name = field.getName();
String modify = Modifier.toString(field.getModifiers());
String classType = field.getType().getSimpleName();
field.setAccessible(true);
Object value = field.get(obj);// 私有属性需要获取权限才可以
System.out.println("superPropertyName: " + modify+ " " + classType + " " + name + "=" + value);
}
}

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); //方法调用  注意invoke的第一个参数为方法对应的类的实例。

UserDTO dto = new UserDTO();
dto.setId("");
System.out.println(dto.getClass().getMethod("getId").invoke(dto));
     /**
* 获取方法并调用方法
* @param strName
* @param methodName
* @param orgs
* @param classes
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public void getRunMethodByMethodName(String strName, String methodName, Object[] orgs, Class<?>[] classes) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
String strClass = getClassName(strName);
Class<?> clazz = Class.forName(strClass);
Class<?> superClazz = clazz.getSuperclass();
Object obj = clazz.newInstance();
Method[] methodArray = clazz.getDeclaredMethods();
Method[] supeMethodArray = superClazz.getDeclaredMethods();
Method[] sumMethodArray = (Method[])ArrayUtils.addAll(methodArray, supeMethodArray);
for(Method method : sumMethodArray){
String modifier = Modifier.toString(method.getModifiers());
String returnType = method.getReturnType().getSimpleName();
String name = method.getName();
Parameter[] parameters = method.getParameters();
Annotation[] annoArray = method.getAnnotations();
String strAnno = "";
for(Annotation anno : annoArray){
strAnno += "@"+anno.annotationType().getSimpleName();
}
String strPara = "";
for(Parameter para : parameters){
strPara+=para.getType().getSimpleName() + " " + para.getName() + ",";
}
System.out.println("method:----"+strAnno + " " + modifier + " " + returnType + " " + name + "(" + strPara +")");
}
Method method = clazz.getMethod(methodName, classes);
System.out.println("header: " + method.invoke(obj, orgs));
}

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:  兔子只有$$$$1@@@@@@头

5. 构造体方法

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

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

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

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

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

  1. 反射机制(Java)

    反射机制 今天闲来无事,对反射机制http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html阅读一番,整理了下这方面的知识以及自己的一些心得 ...

  2. Java:描述反射机制的作用?举几个反射的应用?

    比较全的解释了:JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方 ...

  3. Java 中的反射机制

    JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...

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

    JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...

  5. java反射机制 + Method.invoke解释 getMethod + 反射理解

    功能: 通过读取另一个Dll去创建一个控件(Form,Button,TextBox,DataGridView),然后对当中一些属性进行检查. 创建控件的大致流程是,Assembly->Modul ...

  6. 5. Java反射机制

    Java反射机制   问题: 在运行时,对一个JAVA类,能否知道属性和方法:能否调用它的任意方法? 答案是可以的,JAVA提供一种反射机制可以实现. 目录 什么是JAVA的反射机制 JDK中提供的R ...

  7. java反射机制(2)

    首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Refle ...

  8. Java反射机制剖析(一)-定义和API

    1.     什么是Java反射机制 Java的反射机制是在程序运行时,能够完全知道任何一个类,及其它的属性和方法,并且能够任意调用一个对象的属性和方法.这种运行时的动态获取就是Java的反射机制.其 ...

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

    首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Refle ...

  10. java反射机制(1)

      百度百科: java 反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方 ...

随机推荐

  1. Nodejs使用多个分隔符分隔字符串

    在nodejs中当需要使用多个分隔符分隔字符串时,可以使用正则表达式作为split函数的参数,具体使用如下: var str = "111@222#333 444@555# 666 777& ...

  2. Python twilio发短信实践

    twilio注册地址   注册的时候可能会报错   最好是*** -->注册-->注册完毕后代码运行是不需要***的 https://www.twilio.com/console 需要pi ...

  3. 管理MariaDB

    查看当前用户信息 MariaDB [aa]> select user(); 查看所有存储用户信息 MariaDB [aa]> desc mysql.user; MariaDB [aa]&g ...

  4. windows下GitHub的安装、配置以及项目的上传过程详细介绍

    概要 本文主要介绍了在Win10系统中安装Github终端.如何配置安装好的Git终端以及如何利用Git终端将自己的项目上传到远程服务器中 操作必备 win10系统电脑一台.良好的互联网连接.GitH ...

  5. Python:员工信息增删改查

    一:需求 homework.txt文件中有如下格式的人员信息: 1,Jack Wang,28,13451024608,HR,2015‐01‐072,Rain Wang,21,13451054608,I ...

  6. [UE4]虚幻4链接独立服务器

    如果虚幻4只做客户端的话,应该怎么连接服务器呢? 官方并没有提供蓝图的网络函数,C++里面有. 一.自己实现,提供接口给蓝图使用. 二.第三方插件.插件下载地址:https://github.com/ ...

  7. 去掉user agent stylesheet 浏览器默认样式 [ 2.0 版本 ]

    今天在写一个网页的时候发现一个问题,我的table的样式很奇怪,也没有设置什么样式,跟其他的页面不一样,打开开发者工具一看,发现有这么点样式: 其中右上角:user agent stylesheet ...

  8. numpy.ravel() vs numpy.flatten()

    首先声明两者所要实现的功能是一致的(将多维数组降为一维),两者的区别在于返回拷贝(copy)还是返回视图(view),numpy.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflec ...

  9. third party sales process 继续说

    Trading company: A vendor或production plant: B END Customer: C third party sales与individual purchasin ...

  10. java下载excel,excel从数据库获取数据

    <!-- poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId&g ...