java反射理解

一、反射的定义:

 

二、反射用来做什么:在程序运行时,取得一个已知名称的类(Class)的内部信息,包括其modifiers(修饰符),fields(属性),methods(方法),constructors(构造器),并可用于改变fieds的内容和调用methods,有利于降低代码耦合度。

 

三、反射的使用:

 

1. 一个基本的UserBean类:

package com.neo.entity;

public class UserBean {

    private long userId;

    private String name;

    public UserBean(long userId, String name) {
        this.userId = userId;
        this.name = name;
    }

    public UserBean() {
    }

    public String getName(){
        return name;
    }

    public long getUserId(){
        return userId;
    }

    //静态含参的方法
    public static void staticMethod(String devName){
        System.out.println("I m a static method,"+devName);

    }

    //公共的无参方法
    public void publicMethod(){
        System.out.println("I m a public method!");
    }

    //私有的无参方法
    private void privateMethod(){
        System.out.println("I m a private method!");
    }
}

 

2. 创建Class对象的3种方式:

//1、通过 Class 对象的 forName() 静态方法来获取,用的最多,参数可能不存在,会抛出异常
Class clazz1 = Class.forName("com.neo.entity.UserBean");

//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
//  这说明任何一个类都有一个隐含的静态成员变量 class
Class clazz2 = UserBean.class;

//3、通过对象调用 getClass() 方法来获取
UserBean userBean = new UserBean();
Class clazz3 = userBean.getClass();

 

3. Class类常用的方法:

getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。 getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型,无参方法,则不传
parameterTypes这个参数。

getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

getModifiers():获取成员变量或者方法的修饰符
getType():获取成员变量或者方法的返回值
getName():获取成员变量或者方法的名称的全称
getSimpleName:方法名称的简称
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

 

4. 获取成员变量:

//获取成员变量
Class userBeanClass = UserBean.class;
Field[] fields = userBeanClass.getDeclaredFields();
for (Field field : fields) {
    //获取修饰符
    String modifierStr = Modifier.toString(field.getModifiers()) ; // `private`
    System.out.println(modifierStr);
    //获取参数类型
    String typeStr = field.getType().getSimpleName() + " "; // `String`
    System.out.println(typeStr);
    //获取方法名称
    String nameStr = field.getName(); // `userName`
    System.out.println(nameStr);
}

 

5. 获取成员方法:

//获取成员方法
Class userBeanClass = UserBean.class;
Method[] methods = userBeanClass.getDeclaredMethods();
for (Method method : methods) {
    //获取修饰符
    String modifierStr = Modifier.toString(method.getModifiers()); // public static
    System.out.println(modifierStr);
    //获取返回值类型
    String typeStr = method.getReturnType().getSimpleName() ; // void
    System.out.println(typeStr);
    //获取方法名
    String nameStr = method.getName(); // staticMethod
    System.out.println(nameStr);
    //循环获取参数
    Class[] parameters = method.getParameterTypes();
    for (Class parameter : parameters) {
       String param = parameter.getSimpleName() + " "; // String
        System.out.println(param);
    }
}

 

6. 获取构造函数:

//获取构造函数
Class userBeanClass = UserBean.class;
Constructor[] constructors = userBeanClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
    //获取修饰符
    String modifierStr = Modifier.toString(constructor.getModifiers()) + " ";
    System.out.println(modifierStr);
    //构造器名字
    String nameStr = constructor.getName();
    System.out.println(nameStr);
    Class[] parameters = constructor.getParameterTypes();
    for (Class parameter : parameters) {
        //获取参数
        String parmStr = parameter.getSimpleName();
        System.out.println(parmStr);
    }
}

 

 7. invoke方法使用:

1. static修饰的方法,直接使用:

//调用名称为staticMethod的方法
method.invoke(null,"bydemo");


2. 非静态方法,需实例化对象:

//调用名称为publicMethod的方法
//获取UserBean类的Class对象
Class clazz=Class.forName("com.neo.entity.UserBean");
//创建实例对象
Object object = clazz.newInstance();
Method method = clazz.getMethod("publicMethod");
method.invoke(object);

 

8. 实例:

实例1

    //获取UserBean类的Class对象
try {
    Class clazz=Class.forName("com.neo.entity.UserBean");
    //创建无参对象
    Object object = clazz.newInstance();
    //通过方法名称获取无参数方法
    Method method = clazz.getMethod("publicMethod");
    //有参数的方法
    //Method hmethod = clazz.getMethod("publicMethod",String.class);
    method.invoke(object);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

 

实例2

Class uc = UserBean.class;
Method[] methods = uc.getDeclaredMethods();
for(Method method : methods){
    //判断是否是静态方法
    if(Modifier.isStatic(method.getModifiers())){
        try {
            method.invoke(null,"bydemo");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }else {
        Class[] classes = {long.class,String.class};
        try{
            Constructor constructor = uc.getDeclaredConstructor(classes);
            //构造一个含参对象
            Object us = constructor.newInstance(1l,"by");
            if(Modifier.isPrivate(method.getModifiers())){
                //设置私有方法可调用
                method.setAccessible(true);
            }
            method.invoke(us);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

} 

 

9. 反射类库jOOR使用(地址):

 

 1. 引入依赖

<dependency>
  <groupId>org.jooq</groupId>
  <artifactId>joor-java-8</artifactId>
  <version>0.9.7</version>
</dependency>

 

2. 一个简单的例子

// All examples assume the following static import:
import static org.joor.Reflect.*;

String world = on("java.lang.String")  // Like Class.forName()
                .create("Hello World") // 通过constructor构造实例对象
                .call("substring", 6)  // Call most specific matching substring() method
                .call("toString")      // Call toString()
                .get();                // Get the wrapped object, in this case a String

 

3. 简单使用

package com.example.demo.reflect;

import static org.joor.Reflect.*;
public class JoorReflectDemo {

    public static void main(String[] args) {
        on("com.example.demo.entity.UserBean")
                .create(1l,"hello").
                call("staticMethod","hello");
            }
}

 

 

参考一:http://www.cnblogs.com/ysocean/p/6516248.html

参考二:https://droidyue.com/blog/2017/01/09/joor-examples

posted @ 2018-05-31 20:47  艾白羊  阅读(161)  评论(0)    收藏  举报