Java 反射

Java反射机制

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

Java反射应用

如果想在跨网络的远程平台上创建和运行对象的能力,那么可以通过反射来实现,也就是远程方法调用(RMI),它允许一个Java程序将对象分布到多台机器上。例如可以将计算划分为许多小的计算单元,分布到空闲的机器上运行,从而提高运算速度。

反射在java EE框架(Spring、Struts、Hibernate等)中应用是非常广泛的,最大的用途就是支持以声明式的方法(在XML中)来描述应用的行为。例如Struts中XML中声明一个Action,框架的作者在开发框架时是不知道开发者会定义什么类,所以只能根据类名通过反射机制来创建对象。

<action name="Welcome" class="com.example.Welcome">
    <result>/Welcome.jsp</result>
</action>
public class Welcome extends ExampleSupport {
  public String execute() throws Exception {
    ......
    return SUCCESS;
  }
  ......
}

RTTI(Run-Time Type Information)和反射之间的区别在于,RTTI是编译器在编译时打开和检查.class文件。反射机制是在运行时打开和检查.class文件,.class 文件在编译时是不和获取的。

Java反射运用示例

普通的User实体类

import java.io.Serializable;

/**
 * Created by yrs on 2017/7/13.
 */
public class User implements Serializable{
    private int age;
    private String name;

    public User() {

    }

    public User(int age, String name){
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

输出类信息的工具类ReflectUtil

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * Created by yrs on 2017/7/13.
 */
public class ReflectUtil {

    public void printClassInfo(Class<?> object) {
        System.out.println("类名:" + object.getName());

        Class<?> ParentClass = object.getSuperclass();
        System.out.println("父类名:" + ParentClass.getName());

        Class<?> interfaces[] = object.getInterfaces();
        System.out.println("类实现的接口:");
        for (Class<?> inter: interfaces) {
            System.out.println("  " + inter.getName());
        }
    }

    public void printClassConstructor(Class<?> object) {
        Constructor<?> constructors[] = object.getConstructors();
        System.out.println("类的构造器:");
        for (Constructor<?> constructor: constructors) {
            System.out.println("  构造器名:" + constructor.getName());
            System.out.println("  构造器参数数量:" + constructor.getParameterCount());
            System.out.print("  参数类型:");
            Class<?> types[] = constructor.getParameterTypes();
            for (Class<?> type: types) {
                System.out.print("  " + type.getName());
            }
            System.out.println();
        }
    }

    public void printField(Class<?> object) {
        //获取本类的字段,包括public、protect、private修饰的字段,但不包括父类的字段
        Field[] fields = object.getDeclaredFields();
        //获取类实现的接口或父类的字段,
        //Field[] fields = object.getFields();
        System.out.println("类的字段:");
        for (Field field: fields) {
            System.out.println("  " + field.getType().getName() + " " + field.getName());
        }
    }

    public void printMethod(Class<?> object) {
        //获取本类的方法,但不包括父类的方法
        Method[] methods = object.getDeclaredMethods();
        //获取类的所有方法,包括父类的方法
        //Method[] methods = object.getMethods();
        System.out.println("类的方法:");
        for (Method method: methods) {
            System.out.print("  " + method.getReturnType().getName() + " " + method.getName() + "(");
            for (Parameter parameter: method.getParameters()) {
                System.out.print(parameter.getType().getName() + " " + parameter.getName());
            }
            System.out.println(")");
        }
    }

}

测试类TestReflect

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by yrs on 2017/7/13.
 */
public class TestReflect {

    public static void main(String [] args) throws Exception {
        //查看类相关的信息
        Class<?> userClass = Class.forName("com.yrs.proxy.reflect.User");
        ReflectUtil reflectUtil = new ReflectUtil();
        reflectUtil.printClassInfo(userClass);
        reflectUtil.printClassConstructor(userClass);
        reflectUtil.printField(userClass);
        reflectUtil.printMethod(userClass);


        //实例化一个类的对象,并初始化
        User user = (User)userClass.newInstance();
        user.setName("ByrsH");
        user.setAge(23);
        System.out.println(user.getName() + " " + user.getAge());

        //通过反射操作某个类的属性
        Object object = userClass.newInstance();
        Field field = userClass.getDeclaredField("age");
        field.setAccessible(true);
        field.set(object,18);
        System.out.println(field.get(object));

        //通过反射调用某个方法
        Method methodSet = userClass.getDeclaredMethod("setName", String.class);
        methodSet.setAccessible(true);
        methodSet.invoke(object, "yrs");

        Method methodGet = userClass.getDeclaredMethod("getName");
        methodGet.setAccessible(true);
        System.out.println(methodGet.invoke(object));
    }

}

输出

类名:com.yrs.proxy.reflect.User
父类名:java.lang.Object
类实现的接口:
  java.io.Serializable
类的构造器:
  构造器名:com.yrs.proxy.reflect.User
  构造器参数数量:0
  参数类型:
  构造器名:com.yrs.proxy.reflect.User
  构造器参数数量:2
  参数类型:  int  java.lang.String
类的字段:
  int age
  java.lang.String name
类的方法:
  java.lang.String getName()
  void setName(java.lang.String arg0)
  void setAge(int arg0)
  int getAge()
ByrsH 23
18
yrs

代码下载https://github.com/ByrsH/Design-Patterns/tree/master/Design%20Patterns/src/main/java/com/yrs/proxy/reflect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值