什么是JAVA的反射机制?有什么作用?

发布网友 发布时间:2022-04-23 04:07

我来回答

4个回答

懂视网 时间:2022-04-14 11:25

如上面这段代码,在静态语言中,在编译阶段编译器就会报错。而对于动态语言,是可以修改变量类型的,如下面:

i = 1
i = ‘hi’

1. 先尝试看看第一个问题,什么是反射机制?

在运行时环境,动态获取类的信息以及动态调用对象的方法的功能,就是reflection机制。

2. 哪些地方需要反射?

* 运行时判断任何一个对象所属的类
* 运行时构造任何一个类的对象
* 运行时判断任何一个类所具有的成员变量和方法
* 运行时调用任何一个对象的方法

3. 反射的使用?

先看看java reflection api, Class类是反射的入口点。有下面3种方式获取:

1. Class.forName(“java.util.Data”)
2. T.getClass()
3. T.class

一个Class对象实际表示一个类型,但这个类型不一定是一种类。比如说int不表示类,但是int.class是一个Class类型的对象。

注:数组类型,使用getName会返回一个很奇怪的名字,如:

System.out.println(Double[].class.getName());
显示打印的值如下:
[Ljava.lang.Double;

创建一个类的实例newInstance方法:使用默认的构造函数,没有参数

T.class.newInstance();
Object objCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

反射分析类的能力:

  • 1. java.lang.reflect包下面有3个类,Field,Method,Constructor,分别用来描述属性,方法,构造函数
  • 2. 还有一个修饰符的获取,Modifier
  • 4. 一个反射的简单例子程序:

    package com.lifeware.study.reflection;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    public class ReflectTetser {
    public Object copy(Object obj) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
    Class classType = obj.getClass();
    System.out.println(classType.getName());
    Object objCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

    Field[] fields = classType.getDeclaredFields();
    for(Field field:fields){
    System.out.println(field.getName());
    String firstLetter = field.getName().substring(0,1).toUpperCase();
    String getMethodName = “get” + firstLetter + field.getName().substring(1);
    String setMethodName = “set” + firstLetter + field.getName().substring(1);

    Method getMethod = classType.getMethod(getMethodName, new Class[]{});
    Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});

    Object value = getMethod.invoke(obj, new Object[]{});
    setMethod.invoke(objCopy, new Object[]{value});
    }
    return objCopy;
    }
    /**
    * @param args
    * @throws NoSuchMethodException
    * @throws InvocationTargetException
    * @throws IllegalAccessException
    * @throws InstantiationException
    * @throws SecurityException
    * @throws IllegalArgumentException
    */
    public static void main(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    // TODO Auto-generated method stub
    Customer cus = new Customer();
    cus.setId(new Long(100));
    cus.setAge(new Long(50));
    cus.setName(“zhangsan”);
    Customer cuscopy = (Customer) new ReflectTetser().copy(cus);
    System.out.println(cuscopy.getId() + “,” + cuscopy.getAge() + “,” + cuscopy.getName());
    }
    }
    class Customer{
    private Long id;
    private Long age;
    private String name;

    public Customer(){

    }

    public Long getId(){
    return id;
    }

    public Long getAge(){
    return age;
    }

    public String getName(){
    return name;
    }

    public void setId(Long id){
    this.id = id;
    }

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

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

    5. 当然,反射写通用的数组代码时,还需要用到:java.lang.reflect.Array

    public static Object goodArrayGrow(Object a){
    Class c1 = a.getClass();
    if(!c1.isArray()){
    return null;
    }
    Class componentType = c1.getComponentType();
    int length = Array.getLength(a);
    int newLength = length * 11/10 + 10;
    Object newArray = Array.newInstance(componentType, newLength);
    System.arraycopy(a, 0, newArray, 0, length);

    return newArray;
    }

    动态代理

    动态代理部分:想清楚下面四个问题

    1.什么是动态代理?
    一种用于转发请求,进行特殊处理的机制,“动态”应该指的是“运行期”。
    2.为什么使用动态代理?
    可以对请求进行任何处理(如事务,日志等,这都是网上说的,我当然可以做任何处理)
    3.使用它有哪些好处?
    如上
    4.哪些地方需要动态代理?
    不允许直接访问某些类;对访问要做特殊处理等,我只能想到这些。

    1. 和动态代理有关的有两个类

    1.1 interface InvocationHandler

    只这一个方法, Object invoke(Object proxy, Method method, Object[] args)

    1.2 class Proxy 真正表示动态代理的类,提供两个静态方法:

    Class getProxyClass(ClassLoader loader, Class[] interface)

    用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,

    用来冒充真实的对象。

    Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

    产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),

    它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(…)方法.

    2. 动态机制的实现步骤:

    /**
    * 1. 实现InvocationHandler接口创建自己的调用处理器
    * InvocationHandler handler = new InvocationHandlerImpl(server);
    * 2. 通过Proxy指定ClassLoader对象和一组interface创建动态代理类
    * Class clazz = Proxy.getProxyClass(classLoader,new class[]{…})
    * 3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型:
    * Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class})
    * 4. 通过构造函数创建动态代理类实例,将调用处理器对象作为参数被传入
    * Interface proxy = constructor.newInstance(new Object[]{handler})
    *
    * Proxy中newProxyInstance方法已经封装了步骤2~4,实例如下:
    */

    3. 一个简单实用的例子:

    package com.lifeware.study.reflection;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    public class DynamicProxyTest {
    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    CalculatorProtocol server = new Server();
    InvocationHandler handler = new CalculatorHandler(server);
    CalculatorProtocol client = (CalculatorProtocol)Proxy.newProxyInstance(server.getClass().getClassLoader(),
    server.getClass().getInterfaces(), handler);
    int result = client.add(3, 2);
    System.out.println(“3+2=” + result);
    result = client.subtract(5, 2);
    System.out.println(“5-2=” + result);
    }
    }
    //定义一个接口协议
    interface CalculatorProtocol{
    public int add(int a,int b);
    public int subtract(int a,int b);
    }
    //实现接口协议
    class Server implements CalculatorProtocol{
    public int add(int a,int b){
    return a+b;
    }

    public int subtract(int a,int b){
    return a-b;
    }
    }
    class CalculatorHandler implements InvocationHandler{
    private Object objOriginal;
    public CalculatorHandler(Object obj){
    this.objOriginal = obj;
    }

    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
    //可加入预处理
    Object result = method.invoke(this.objOriginal, args);
    return result;

    }

    }

    ~~EOF~~

    热心网友 时间:2022-04-14 08:33

    现在学习Java的平台有很多,B站或者是腾讯课堂都是可以的,我们在B站分享了很多经典的Java视频教程,都是开源的,你可以去看看。

    热心网友 时间:2022-04-14 10:08

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

    热心网友 时间:2022-04-14 11:59

    定义
    反射机制是Java语言中一个非常重要的特性,它允许程序在运行时进行自我检查,同时也允许其对内部成员进行操作。由于反射机制能够实现在运行时对类进行装载,因此能够增加程序的灵活性,但是不恰当地使用反射机制,也会严重影响系统的性能。
    具体而言,反射机制的主要功能主要有:①得到一个对象所属的类,②获取一个类的所有成员变量和方法,③在运行时创建对象,调用对象的方法。
    反射机制的作用:
    1,反编译:.class–>.java
    2,通过反射机制访问java对象的属性,方法,构造方法等;
    学习java,就来北京尚学堂!

    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com