栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java—反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java—反射

目录

一、反射机制

1.1 Java Reflection

1.2 Java反射机制原理示意图

1.3 Java反射机制可以完成

1.4 反射相关的主要类

1.5 反射的优点和缺点

1.6 反射调用优化—关闭访问检查

二、Class类

2.1 基本介绍

2.2 Class类的常用方法


一、反射机制

1.1 Java Reflection

1.反射机制允许程序在执行期借助于ReflectionAPI取得热河类的内部信息(比如成员变量,构造器,成员方法等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到

2.加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以称之为:反射

1.2 Java反射机制原理示意图

1.3 Java反射机制可以完成

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

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

        3. 在运行时得到任意一个类所具有的成员变量和方法

        4. 在运行时调用任意一个对象的成员变量和方法

        5. 生成动态代理

1.4 反射相关的主要类

        1. java.lang.Class:代表一个类,Class对象表示某个类加载后在堆中的对象

        2. java.lang.reflect.Method:代表类的方法,Method对象表示某个类的方法

        3. java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器

1.5 反射的优点和缺点

优点:可以动态的创建和使用对象(也是框架底层核心),使用灵活,没有反射机制,框架技术就是失去底层支撑

缺点:使用反射基本是解释执行,对执行速度有影响

1.6 反射调用优化—关闭访问检查

        1. Method和Field、Constructor对象都有setAccessible()方法

        2. setAccessible作用是启动和禁用访问安全检查的开关

        3. 参数值为true表示反射的对象爱国你在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查

package com.learn.reflection.question;

import com.learn.reflection.Cat;

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


public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {

        m1();
        m2();
        m3();
    }
        //传统方法调用hi
        public static void m1() {
            Cat cat = new Cat();
            long start = System.currentTimeMillis();
            for (int i = 0; i < 900000000; i++) {
                cat.hi();
            }
            long end = System.currentTimeMillis();
            System.out.println("m1() 耗时" + (end - start));
        }

        //反射机制调用方法hi
        public static void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class cls = Class.forName("com.learn.reflection.Cat");
            Object o = cls.newInstance();
            Method hi = cls.getMethod("hi");
            long start = System.currentTimeMillis();
            for (int i = 0; i < 900000000; i++) {
                hi.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("m2() 耗时" + (end - start));
        }

    //反射调用优化 + 关闭访问检测
    public static void m3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.learn.reflection.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        hi.setAccessible(true);//在反射调用方法时,取消访问检查
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("m3() 耗时" + (end - start));
    }
}

运行结果如下:

m1() 耗时3
m2() 耗时1024
m3() 耗时695

二、Class类

2.1 基本介绍

        1. Class也是类,因此也继承Object类[类图]

        2. Class类对象不是new出来的,而是系统创建的

        3. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次

        4. 每个类的实例都会记得自己是由哪个Class实例所生成

        5. 通过Class对象可以完整地得到一个类的完整结构,通过一系列API

        6. Class对象是存放在堆的

        7. 类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等等)

2.2 Class类的常用方法

 

package com.learn.reflection.class_;

import com.learn.reflection.Car;

import java.lang.reflect.Field;


public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        String classAllPath = "com.learn.reflection.Car";
        //1. 获取到 Car 类 对应的 Class 对象
        // 表示不确定的 Java 类
        Class cls = Class.forName(classAllPath);
        //2. 输出 cls
        System.out.println(cls);//显示cls对象,是哪个类的Class对象 -> com.learn.reflection.Car
        System.out.println(cls.getClass());//输入cls运行类型 java.lang.Class
        //3. 得到包名
        System.out.println(cls.getPackage().getName());//包名
        //4. 得到全类名
        System.out.println(cls.getName());
        //5. 通过 cls 创建对象实例
        Car car = (Car)cls.newInstance();
        System.out.println(car);
        //6. 通过反射获取属性 brand
        Field brand = cls.getField("brand");
        System.out.println(brand.get(car));//宝马
        //7. 通过反射给属性赋值
        brand.set(car,"奔驰");
        System.out.println(brand.get(car));
        //8. 希望可以得到所有的属性(字段)
        System.out.println("=======所有的字段属性=======");
        Field[] fields = cls.getFields();
        for(Field f : fields) {
            System.out.println(f.getName());//名称
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/821992.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号