• 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"}});
        }
        
    }


      

  • 相关阅读:
    搜狗输入法赏析
    第二次冲刺个人总结05
    程序员的自我修养阅读笔记01
    第十五周学习总结
    mysql 查询优化
    mysql explain 详解
    nginx基本配置与参数说明
    input输入框实现联想关键词功能
    JS图片懒加载
    mysql中timestamp,datetime,int类型的区别与优劣
  • 原文地址:https://www.cnblogs.com/tc971121/p/10544391.html
Copyright © 2020-2023  润新知