java之反射机制

一.Class类

  1.在面向对象的世界里,万事万物皆对象。

    在java对象里,只有静态的成员或方法(属于类的)和基本的数据类型(有包装类来弥补)不是对象,类也是对象,是java.lang.Class类的实例对象。

  2.类类型的三种表达方式:

    1.类名.class:在每个类中都有一个隐含的静态成员变量。

    2.实例对象.getClass()。

    3.Class.forName("类的全称")。

  3.Class.forName("类的全称")不经代表了类的类类型还代表了动态加载类(在编译时刻加载类是静态加载类,在运行时刻加载类是动态加载类)。

二.反射的原理

  反射是通过类加载器加载类时,将类信息存储在数据区,然后提供一个class对象来作为访问该类信息的接口。

如下操作:

  一.通过反射来打印类的信息

  package com.ztc.reflect;

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


/**
 * 反射的工具类
 * @author DELL
 *
 */
public class ClassUtil {
    
    /**
     * 打印输入对象所属类的方法信息
     * @param object
     */
    public static void printMethod(Object object){
        Class clazz= object.getClass();   //获取当前对象的类类型
        Method[] methods = clazz.getMethods();    //获取类中所有的方法对象
        for (Method method : methods) {
            StringBuilder sBuilder = new StringBuilder();
            sBuilder.append(Modifier.toString(method.getModifiers()) + " ");
            sBuilder.append(method.getReturnType().getName() + " ");
            sBuilder.append(method.getName() + "(");
            Class[] paramClazzs = method.getParameterTypes();
            int count = 1;
            for (Class paramClazz : paramClazzs) {
                if (count == paramClazzs.length) {
                    sBuilder.append(paramClazz.getName() + " var");
                }else {
                    sBuilder.append(paramClazz.getName() + " var,");
                }
                count++;

            }
            sBuilder.append(")");
            System.out.println(sBuilder.toString());    
        }
    }
    
    /**
     * 打印所有的构造方法
     * @param object
     */
    public static void printContructors(Object object){
        Class clazz = object.getClass();
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            StringBuilder sBuilder = new StringBuilder();
            sBuilder.append(Modifier.toString(constructor.getModifiers()) + " ");
            sBuilder.append(constructor.getName() + " ");
            sBuilder.append("(");
            Class[] paramClazzs = constructor.getParameterTypes();
            int count = 1;
            for (Class paramClazz : paramClazzs) {
                if (count == paramClazzs.length) {
                    sBuilder.append(paramClazz.getName() + " var");
                }else {
                    sBuilder.append(paramClazz.getName() + " var,");
                }
                count++;
            }
            sBuilder.append(")");
            System.out.println(sBuilder.toString());    
        }
    }
    
    /**
     * 打印出所有的成员变量
     * @param object
     */
    public static void printFileds(Object object){
        Class clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            StringBuilder sBuilder = new StringBuilder();
            sBuilder.append(Modifier.toString(field.getModifiers()) + " ");
            sBuilder.append(field.getDeclaringClass().getName() + " ");
            sBuilder.append("var;");
            System.out.println(sBuilder.toString());
        }
    }
    
}

二.通过反射方法来绕过泛型(因为反射是动态加载类),当反射私有方法或字段时,需要method.setAccessible(true)/field.setAccessible(true);

package com.ztc.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * 通过方法的反射操作绕过泛型
 * @author DELL
 *
 */
public class MethodReflect {

    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<>();
        Class clazz = list.getClass();
        try {
            Method method = clazz.getMethod("add", Object.class);
            method.invoke(list, 1);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(list);
            
    }
}
package com.ztc.reflect;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;

import org.junit.Test;
import org.junit.internal.Throwables;
import org.junit.validator.PublicClassValidator;

//反射类的方法
public class Demo3 {
    
    //反射方法public Class[] aa(String name,int[] age)
    @Test
    public void test1() throws Exception{
        Class class1 = Class.forName("cn.com.reflect.Person");
        Method method = class1.getMethod("aa", String.class,int[].class);
        method.invoke(class1.newInstance(), "ss",new int[]{1,2});
        
        
    }
    
    //反射方法public void aa(int in)
    @Test
    public void test2() throws Exception{
        Class class1 = Class.forName("cn.com.reflect.Person");
        Method method = class1.getMethod("aa3", int.class);
        method.invoke(class1.newInstance(), 5);
    }
    
    //反射方法private void aa(double d)
    @Test
    public void test3() throws Exception{
        Class class1 = Class.forName("cn.com.reflect.Person");
        Method method = class1.getDeclaredMethod("aa",double.class);
        method.setAccessible(true);
        method.invoke(class1.newInstance(), 11);
        
    }
    
    //对静态方法的反射
    @Test
    public void test4() throws Exception{
        Class class1 = Class.forName("cn.com.reflect.Person");
        Method method = class1.getMethod("aa3", int.class);
        method.invoke(null, 5);
    }
    
    //反射类的主方法public static void main(String args[]){}
    @Test
    public void test5() throws Exception{
        Class class1 = Class.forName("cn.com.reflect.Person");
        Method method = class1.getMethod("main",String[].class);
        method.invoke(null, new Object[]{new String[]{"s"}});
    }
    
}


  

原文地址:https://www.cnblogs.com/tc971121/p/10544391.html