A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© One丶Life 中级黑马   /  2015-11-22 20:19  /  328 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1 反射机制

1、介绍
        JAVA反射机制实在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为JAVA反射机制。
        要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。
        通俗来讲,反射就是通过class文件对象,去使用该文件中的成员变量、构造方法、成员方法。
        Class类:
                成员变量:Field
                构造函数:Constructor
                成员方法:Method

2、获取calss文件对象的方式
  • Object类的getClass()方法
  • 数据类型的静态属性class
  • Class类中的静态方法:public static Class forName(String className)
    在开发中一般使用第三种,因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。


1.1、通过反射获取构造方法并使用

1、获取构造方法:
  • public Constructor[] getConstructors();所有公共构造方法
  • public Constructor[] getDeclaredConstructors();所有构造方法
  • public Constructor<T> getConstructor(Class... parameterTypes);单个公共构造方法
         参数表示:要获取的构造方法的构造参数的个数及数据类型的class字节码文件对象。、
  • public Constructor<T> getDeclaredConstructor(Class... parameterTypes);单个任意构造方法

2、获取无参构造方法并使用

package cn.ref;

import java.lang.reflect.Constructor;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {

        //获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //获取单个构造方法
        Constructor con = c.getConstructor();//返回的是构造方法对象
        
        //通过获取的构造方法创建一个新实例
        Object obj = con.newInstance();
        System.out.println(obj);
        Person p = (Person)obj;
        p.function();
    }
}


3、获取带参构造方法并使用
package cn.ref;

import java.lang.reflect.Constructor;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        //获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //获取带参构造方法
        Constructor con = c.getConstructor(String.class,int.class,String.class);//返回的是构造方法对象
        
        //通过获取的构造方法创建一个新实例
        Object obj = con.newInstance("张三",20,"男");
        System.out.println(obj);
        Person p = (Person)obj;
        System.out.println(p.getName());
    }
}


4、获取私有构造方法并使用
package cn.ref;

import java.lang.reflect.Constructor;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        // 获取私有构造方法
        Constructor con = c.getDeclaredConstructor(String.class);// 返回的是构造方法对象
        //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
        con.setAccessible(true);//设置为true才能访问私有,否则报java.lang.IllegalAccessException
        // 通过获取的构造方法创建一个新实例
        Object obj = con.newInstance("张三");
        System.out.println(obj);
        Person p = (Person) obj;
        System.out.println(p.getName());
    }
}

1.2、通过反射获取成员变量并使用

1、获取成员变量
  • public Field getField(String name);获取单个公共成员变量
  • public Field getDeclaredField(String name);获取单个任意成员变量
  • public Field[] getFields();获取所有公共成员变量
  • public Field[] getDeclaredFields();获取所有成员变量

2、获取公共成员变量并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取成员变量
        Field f = c.getField("sex");
        //赋值
        f.set(obj, "女");
        
        System.out.println(obj);
        Person p = (Person) obj;
        System.out.println(p.getSex());
    }
}


3、获取私有成员变量并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取成员变量
        Field f = c.getDeclaredField("name");
        f.setAccessible(true);
        //赋值
        f.set(obj, "张三");
        
        System.out.println(obj);
        Person p = (Person) obj;
        System.out.println(p.getName());
    }
}


1.3、通过反射获取成员方法并使用

1、获取成员方法
  • public Method getMethod(String name, Class... parameterTypes);获取单个公共成员方法
  • public Method getDeclaredMethod(String name, Class... parameterTypes);获取单个任意成员方法
  • public Method[] getMethods();获取所有公共成员方法
  • public Method[] getDeclaredMethods();获取所有成员方法

2、获取无参无返回值成员方法并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取无参成员方法
        Method m = c.getMethod("function");
        //调用方法
        m.invoke(obj);
    }
}

3、获取带参带返回值成员方法并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        // 通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取带参成员方法
        Method m = c.getMethod("function",String.class,int.class);
        // 调用方法
        Object o = m.invoke(obj,"hello",20);
        System.out.println(o);
    }
}


4、获取私有成员方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
    public static void main(String[] args) throws Exception {   
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        // 通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取私有成员方法
        Method m = c.getDeclaredMethod("show");
        m.setAccessible(true);
        // 调用方法
        m.invoke(obj);
    }
}


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马