java反射机制及其详解

简介: java反射机制及其详解




有时候我们做项目的时候不免需要用到大量配置文件,就拿框架举例,通过这些外部文件配置,在不修改的源码的情况下,来控制文件,就要用到我们的反射来解决
假设有一个Cat对象

public class Cat {
    private String name = "招财猫";
    public void hi(){
        System.out.println("hi "+name);
    }
}

传统调用方法

public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //传统的方式 new 对象 -》 调用方法
        Cat cat = new Cat();
        cat.hi();
    }
}

现在有一个配置文件

classfullpath=Reflection.com.hspedu.Cat
method=hi

反射调用

/反射问题的引入
public class ReflectionQuestion { 
//1.使用Properties类,可以读写配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\Reflection\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();
        //使用反射机制来解决
        //(1)加载类,返回Class类型的对象
        Class cls = Class.forName(classfullpath);
        //(2)通过 cls 得到你加载的类 com.hspedu.Cat
        Object o = cls.newInstance();
        System.out.println("o的运行类型="+o.getClass());
        //(3)通过 cls 得到你加载的类 Reflection.com.hspedu.Cat 的 methodName 的方法对象
        //即: 在反射中,可以把方法视为对象(万物皆对象)
        Method method1 = cls.getMethod(method);
        //(4)通过method1 调用方法:即通过方法对象实现调用方法
        System.out.println("=========================");
        method1.invoke(o);
    }
}

运行结果:


反射的强大之处就是可以在外部文件上不修改源码的情况下来控制程序


反射机制

反射机制允许程序在执行的时候借助我们Reflection API取得任何类的内部信息,并且能操作对象的属性及方法。反射在设计模式和框架底层都会用到
(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,形象的称之为:反射

解释

//反射问题的引入
public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
           //1.使用Properties类,可以读写配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\Reflection\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();
        //使用反射机制来解决
        //(1)加载类,返回Class类型的对象
        Class cls = Class.forName(classfullpath);
        Class cls2 = Class.forName(classfullpath);
        System.out.println(cls.hashCode());
        System.out.println(cls2.hashCode());
    }
}

运行结果:

可以看出来他们指向同一个对象


java反射机制可以完成
1.在运行时判断任意一个对象所属的类

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

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

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

5.生成动态代理


反射调用优化

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

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

public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        m1();
        m2();
    }
    //传统方式来调用hi
    public static void m1(){
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for(int i=0;i<90000000;i++){
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统方法来调用hi 耗时="+(end-start));
    }
    //反射机制调用方法hi
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("Reflection.com.hspedu.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        long start = System.currentTimeMillis();
        for(int i=0;i<90000000;i++){
            hi.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射方法来调用hi 耗时="+(end-start));
    }
}

运行结果:

差距这么大有什么方法优化吗

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

目录
相关文章
|
11天前
|
存储 监控 算法
Java中的内存管理:理解Garbage Collection机制
本文将深入探讨Java编程语言中的内存管理,着重介绍垃圾回收(Garbage Collection, GC)机制。通过阐述GC的工作原理、常见算法及其在Java中的应用,帮助读者提高程序的性能和稳定性。我们将从基本原理出发,逐步深入到调优实践,为开发者提供一套系统的理解和优化Java应用中内存管理的方法。
|
3天前
|
存储 算法 Java
Java HashSet:底层工作原理与实现机制
本文介绍了Java中HashSet的工作原理,包括其基于HashMap实现的底层机制。通过示例代码展示了HashSet如何添加元素,并解析了add方法的具体过程,包括计算hash值、处理碰撞及扩容机制。
|
5天前
|
Java 程序员 开发者
深入探索Java中的异常处理机制
【10月更文挑战第12天】 本文旨在全面解析Java的异常处理机制,从基本概念到高级技巧,为读者提供一个清晰的学习路径。我们将探讨try-catch-finally块的使用、throws关键字的作用以及自定义异常类的创建方法。此外,文章还将通过实际案例分析,展示如何有效利用Java异常处理来提高程序的鲁棒性和可维护性。无论是初学者还是经验丰富的开发者,都能在本文中找到有价值的信息和实用的建议。
|
17天前
|
Java 程序员
深入理解Java中的异常处理机制
本文将深入探讨Java中的异常处理机制,通过详细的示例代码和解释,帮助读者更好地理解和应用Java异常处理。我们将从基本概念入手,逐步深入到高级特性,如自定义异常、异常链以及最佳实践。
19 8
|
13天前
|
Java 开发者
Java中的异常处理机制:理解与应用
在Java编程中,异常处理是一个重要的概念。它允许开发者通过检测和响应错误情况来增强程序的健壮性和可靠性。本文将深入探讨Java异常处理的基本概念、不同类型的异常以及如何使用try-catch-finally块来捕获和处理异常。我们还将讨论如何创建自定义异常类,并提供一些最佳实践来有效处理异常。通过阅读本文,您将能够更好地理解和应用Java中的异常处理机制,从而提高您的编程技能和代码质量。
|
14天前
|
Java 程序员 数据库连接
Java中的异常处理机制:理解与应用
在Java编程语言中,异常处理是保证程序健壮性的重要机制。本文将深入探讨Java异常处理的基本概念、不同类型的异常、异常处理的最佳实践以及如何创建自定义异常。通过具体示例,我们将展示如何在Java项目中有效管理和处理异常,从而提高代码的可靠性和可维护性。
|
12天前
|
Java 数据库连接 开发者
深入理解Java中的异常处理机制
本文旨在全面解析Java异常处理机制,从基础概念到高级应用,为读者提供一套完整的异常处理策略。通过实例演示,我们将揭示如何有效利用try-catch-finally语句,以及throw和throws关键字,来构建健壮的Java应用程序。此外,本文还将探讨自定义异常的创建与使用,以及如何通过合理的异常处理提升代码的可维护性和可读性。
|
13天前
|
Java 程序员 编译器
深入理解Java中的异常处理机制
本文旨在深入探讨Java的异常处理机制,揭示其在软件开发过程中的重要性。通过详细解析Java异常的类型、异常处理的方式以及自定义异常的方法,我们将了解如何有效利用异常处理机制来提高代码的健壮性和可维护性。此外,文章还将讨论常见的异常处理最佳实践和陷阱,帮助开发者在编写高质量Java应用时避免常见错误。
|
13天前
|
设计模式 缓存 Java
Java高并发处理机制
Java高并发处理机制
18 1
|
14天前
|
安全 Java 开发者
在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制
【10月更文挑战第3天】在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制,如`synchronized`关键字、`Lock`接口及其实现类(如`ReentrantLock`),还有原子变量(如`AtomicInteger`)。这些工具可以帮助开发者避免数据不一致、死锁和活锁等问题。通过合理选择和使用这些机制,可以有效管理并发,确保程序稳定运行。例如,`synchronized`可确保同一时间只有一个线程访问共享资源;`Lock`提供更灵活的锁定方式;原子变量则利用硬件指令实现无锁操作。
13 2