资讯专栏INFORMATION COLUMN

Reflection:Java反射机制基础

hizengzeng / 2000人阅读

摘要:反射机制是什么反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意一个方法和属性这种动态获取的信息以及动态调用对象的方法的功能称为语言的反射机制反射机制能做什么反射机制主要提供了以下功

反射机制是什么

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

反射机制能做什么

反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判断任意一个类所具有的成员变量和方法

在运行时调用任意一个对象的方法

生成动态代理

反射机制的相关API 通过一个对象获得完整的包名和类名
    @Test
    public void getReflectionName() {
        String str = new String();
        System.out.println(str.getClass().getName()); // java.lang.String
        System.out.println(str.getClass().getSimpleName()); // String
    }
实例化Class类对象(三种方式)
    @Test
    public void getInitClazz() {

        try {
            // 方式一:
            Class clazz_1 = Class.forName("java.lang.String");
            // 方式二:
            Class clazz_2 = new String().getClass();
            // 方式三:
            Class clazz_3 = String.class;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
获取一个对象的父类与实现的接口
    @Test
    public void getParentAndIntefaces() {

        try {
            Class clazz = Class.forName("java.lang.String");
            // 取得父类
            Class parentClass = clazz.getSuperclass();
            System.out.println("clazz的父类为:" + parentClass.getName());// clazz的父类为: java.lang.Object
            
            // 获取所有的接口
            Class intes[] = clazz.getInterfaces();
            System.out.println("clazz实现的接口有:");
            for (int i = 0; i < intes.length; i++) {
                System.out.println((i + 1) + ":" + intes[i].getName());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
通过反射获取属性
    @Test
    public void getFieldsByReflect() {

        try {
                Class clazz = String.class ;
                // 取得本类的全部属性
                Field[] declaredFields = clazz.getDeclaredFields(); 
                // 取得实现的接口或者父类的属性
                Field[] fields = clazz.getFields();
                
                //遍历本类属性
                for (Field field : declaredFields) {
                    // 权限修饰符
                    int mo = field.getModifiers();
                    String priv = Modifier.toString(mo);
                    // 属性类型
                    Class type = field.getType();
                    System.out.println(priv + " " + type.getName() + " " + field.getName() + ";");
                }
                
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
通过反射获取方法函数
    @Test
    public void getMethodsByReflect() {

        try {
            Class clazz = String.class ;
            // 类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法
            Method[] methods = clazz.getMethods();
            // 类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法
            Method[] declaredMethods = clazz.getDeclaredMethods();
            
            //遍历本类属性
            for (Method method : methods) {
                // 权限修饰符
                int mo = method.getModifiers();
                String priv = Modifier.toString(mo);
                //返回值
                Class returnType = method.getReturnType();
                //方法名
                String methodName = method.getName();
                //方法参数类型
                Class[] parameterTypes = method.getParameterTypes();
                //抛出的异常
                Class[] exceptionTypes = method.getExceptionTypes();
            }
            
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
通过反射获取构造方法
    @Test
    public void getConstructorsByReflect() {

        try {
            Class clazz = Class.forName("java.lang.String");
            
            //获取构造方法
            Constructor[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                
                //获取构造方法的参数
                Class[] parameterTypes = constructor.getParameterTypes();
                for (Class clazzType : parameterTypes) {
                    System.out.print(clazzType.getSimpleName() + "   ");
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
通过反射机制设置属性
    @Test
    public void oprFieldsByReflect() {

        try {
            
            Class clazz = Class.forName("java.lang.String");
            //实例化对象
            String str = new String("String");
            //可以直接对 private 的属性赋值
            Field field = clazz.getDeclaredField("hash");
            //改变属性
            field.setAccessible(true);
            //调用映射属性
            field.set(str, 0);
            
            System.out.println(field.get(str));
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
通过反射机制调用方法
    @Test
    public void oprMethodsByReflect() {

        try {
            Class clazz = Class.forName("java.lang.String");
            //实例化一个对象
            String str = new String("String");
            //反射出一个方法
            Method method =  clazz.getMethod("startsWith", String.class);
            //调用映射方法
            Object result = method.invoke(str, "Str");
            
            System.out.println(result);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
实例应用 在泛型为Integer的ArrayList中存放一个String类型的对象
    /**
     * 在泛型为Integer的ArrayList中存放一个String类型的对象
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
           ArrayList list = new ArrayList();
            Method method = list.getClass().getMethod("add", Object.class);
            method.invoke(list, "Java反射机制实例");
            System.out.println(list.get(0));
    }
通过反射取得并修改数组的信息
    /**
     * 通过反射取得并修改数组的信息
     * 
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        int[] temp = { 1, 2, 3, 4, 5 };
        Class demo = temp.getClass().getComponentType();
        
        System.out.println("数组类型: " + demo.getName());
        
        System.out.println("数组长度  " + Array.getLength(temp));
        
        System.out.println("数组的第一个元素: " + Array.get(temp, 0));
        
        Array.set(temp, 0, 100);
        System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0));
    }
通过反射机制修改数组的大小
   /**
     * 通过反射机制修改数组的大小
     * 
     * @throws Exception
     */
    @Test
    public void test() throws Exception {

        int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[] newTemp = (int[]) arrayInc(temp, 15);
        print(newTemp);
        String[] atr = { "a", "b", "c" };
        String[] str1 = (String[]) arrayInc(atr, 8);
        print(str1);
    }

    // 修改数组大小
    private static Object arrayInc(Object obj, int len) {
        Class arr = obj.getClass().getComponentType();
        Object newArr = Array.newInstance(arr, len);
        int co = Array.getLength(obj);
        System.arraycopy(obj, 0, newArr, 0, co);
        return newArr;
    }

    // 打印
    private static void print(Object obj) {
        Class c = obj.getClass();
        if (!c.isArray()) {
            return;
        }
        System.out.println("数组长度为: " + Array.getLength(obj));
        for (int i = 0; i < Array.getLength(obj); i++) {
            System.out.print(Array.get(obj, i) + " ");
        }
        System.out.println();
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67320.html

相关文章

  • ReflectionJava反射机制的应用场景

    近期在维护公司项目的时候遇到一个问题,因为实体类中的 set 方法涉及到了业务逻辑,因此在给对象赋值的过程中不能够使用 set 方法,为了实现功能,所以采用了反射的机制给对象属性赋值,借此机会也了解了反射的一些具体用法和使用场景,分以下两点对反射进行分析: 反射的优势和劣势 反射的应用场景 反射的优势和劣势   个人理解,反射机制实际上就是上帝模式,如果说方法的调用是 Java 正确的打开方式...

    浠ラ箍 评论0 收藏0
  • Java动态性(2) - 之反射机制(Reflection)

    摘要:的动态性反射机制动态编译动态执行代码动态字节码操作动态语言程序运行时可以改变程序得结构或变量类型典型语言等如下代码不是动态语言但有一定的动态性我们可以利用反射机制字节码操作获得类似动态语言的特性的动态性让编程的时候更加灵活反射机制反射机制指 1.Java的动态性 反射机制 动态编译 动态执行JavaScript代码 动态字节码操作 2.动态语言 程序运行时,可以改变程序得结构或变量...

    妤锋シ 评论0 收藏0
  • Java 反射(Reflection)

    摘要:效率运行效率使用反射减低程序的运行效率。开发效率由于反射运用到各个框架中,大大加快了开发的效率。 反射的核心就是Class对象,每一个类被jvm加载都会有一个对应的class对象,这个class对象包含了这个类的结构信息,反射就是会通过反射api反复操作这个class对象(属性,方法,注解,构造器,泛型),但是反射会降低程序的运行效率,比普通方法要慢30倍,通过setAccessble...

    shengguo 评论0 收藏0
  • Java 反射教程

    摘要:反射非常强大和有用。另外,反射可以用在映射结果集的列名到对象的方法。本教程将深入介绍反射。本教程还将清除一些关于范型信息在运行时可用性的认知混淆。类对象使用反射时,起点通常是需要使用反射检视的类的对象。 Java反射可以在运行时检视类、接口、属性和方法,而无需在编译时知道类名、方法名等等。它也同样使用反射支持实例化新的对象、调用方法和get/set属性值。 Java反射非常强大和有用...

    klivitamJ 评论0 收藏0
  • Java反射Java 泛型基础

    摘要:笔记来源反射综述类的使用方法的反射成员变量的反射构造函数的反射类加载机制类的使用在面向对象的世界里,万事万物皆对象。 笔记来源:IMOOC 反射 Java Reflect 综述 Class类的使用 方法的反射 成员变量的反射 构造函数的反射 类加载机制 Class 类的使用 在面向对象的世界里,万事万物皆对象。 但在Java里面有两样东西不是对象:静态的成员、普通数据类型类...

    seanHai 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<