Java反射机制

简介: Java反射机制

1.定义

java的反射(reflection)机制是在java运行状态中,对任意一个类,都能知道这个类的所有方法和属性。 对于任意一个对象, 都能够调用它的任意方法和属性, 也可以修改其部分信息。 这种动态获取值以及动态调用对象的方法就叫做java语言的反射机制

2.用途

  • 在日常中的三方应用开发过程中,经常会遇到某个类的某个成员变量,方法或者是属性是私有的,或者是只对系统应用开放, 这时候就可以利用java的反射机制来获取这些私有成员或者是方法。
  • 反射最重要的用途就是开发各种通用框架, 比如spring中,将所有的类bean交给spring容器管理,无论xml配置bean还是注解配置,当我们从容器中或缺bean来依赖注入时,容器就会读取配置, 而配置中给的就是类的信息 spring根据这些信息,创建那些bean,spirng就动态创建这些类。

3.反射基本信息

java程序中许多对象在运行玩的时候会出现两种类型,运行时类和编译时类,程序需要在运行时发现对象和类的真实信息。而通过反射程序就能判断出该对象和类属于哪些类。

4.反射相关的类

  • Class类:代表类的实体 在运行的java应用程序当中表示类和接口
  • Field类:代表类的成员变量(属性)
  • Method类:代表类的方法
  • Constructor类:代表类的构造方法

Class类

原理

代表类的实体,在运行的java程序中表示类和接口

java文件被编译之后,生成了.class文件,jvm此时就要去解读这个.class文件,被编译后的java文件,.class也被jvm解析为一个对象, 这个对象就是java.lang.Class。 这样,当程序在运行时,每个java文件就最终变成Class类对象的一个实例。我们通过java反射机制,应用到这个实例,就可以去获得甚至是修改这个类的属性和动作,是这个类成为一个动态的类

获取类的方法

方法

作用

getClassLoader()

获得类的加载器

getDeclaredClasses()

返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的)

forName(String className)

根据类名返回类的对象

newInstance()

创建类的实例

getName()

获得类的完整路径名字

获取属性的方法

方法

作用

getField(String name)

获得某个公有的属性对象

getFields()

获得所有公有的属性对象

getDeclaredField(String name)

获得某个属性对象

getDeclaredFields()

获得所有属性对象

获得类中构造器相关

方法

用途

getConstructor(Class...<?> parameterTypes)

获得该类中与参数类型匹配的公有构造方法

getConstructors()

获得该类的所有公有构造方法

getDeclaredConstructor(Class...<?> parameterTypes)

获得该类中与参数类型匹配的构造方法

getDeclaredConstructors()

获得该类所有构造方法

获得类中方法相关的方法

方法

用途

getMethod(String name, Class...<?> parameterTypes)

获得该类某个公有的方法

getMethods()

获得该类所有公有的方法

getDeclaredMethod(String name, Class...<?> parameterTypes)

获得该类某个方法

getDeclaredMethods()

获得该类所有方法

一个简单的例子

一个类:

class Student{
    //私有属性name
    private String name = "hello";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
        System.out.println("Student()");
    }
    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }
    private void eat(){
        System.out.println("i am eat");
    }
    public void sleep(){
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

在进行反射之前我们首先需要拿到其需要反射的类的Class对象, 然后再利用反射机制进行相关操作:

获取Class对象的3中方法:

public class Main {
    public static void main(String[] args) throws ClassNotFoundException { // 受查异常
        Class<?> c1 = Class.forName("Student");  // 1
        Class<?> c2 = Student.class;  // 2
 
        Student student = new Student();
        Class<?> c3 = student.getClass();
 
        System.out.println(c1 == c2);
        System.out.println(c3 == c2);
        System.out.println(c1 == c3);
    }
}

结果输出3个true, 所以, 不管是哪种方法获取的Class对象, 结果都是相同的.

调用不带参数的构造方法

public class Main {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        Class<?> c2 = Student.class;  
        Student student = (Student) c2.newInstance();
    }
}

这里的newInstance()方法返回的是一个Object类, 这里将其强制转换为Student类.

调用私有构造方法

public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
        Class<?> c2 = Class.forName("Student");  // 2
        Constructor<?> constructor = c2.getDeclaredConstructor(String.class, int.class);
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("libo",19);
        System.out.println(student);
    }

结果:

反射修改属性

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<?> c1 = Class.forName("Student");
        Field field = c1.getDeclaredField("name");
        field.setAccessible(true);
        // 使用set改变属性
        Student student = (Student) c1.newInstance();
        field.set(student,"bozimeimei");
        System.out.println(student);
    }
}

反射调用方法

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Class<?> c1 = Class.forName("Student");
        Method method = (Method) c1.getDeclaredMethod("function", String.class);
        method.setAccessible(true);
        Student student = (Student) c1.newInstance();
        method.invoke(student, "hello bozimeimei");
    }
}

反射的优缺点

优点

1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法

2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力

3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺点

1. 使用反射会有效率问题。会导致程序效率降低。

2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。


目录
相关文章
|
23天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
61 2
|
27天前
|
Java 编译器
探索Java中的异常处理机制
【10月更文挑战第35天】在Java的世界中,异常是程序运行过程中不可避免的一部分。本文将通过通俗易懂的语言和生动的比喻,带你了解Java中的异常处理机制,包括异常的类型、如何捕获和处理异常,以及如何在代码中有效地利用异常处理来提升程序的健壮性。让我们一起走进Java的异常世界,学习如何优雅地面对和解决问题吧!
|
2月前
|
存储 算法 Java
Java HashSet:底层工作原理与实现机制
本文介绍了Java中HashSet的工作原理,包括其基于HashMap实现的底层机制。通过示例代码展示了HashSet如何添加元素,并解析了add方法的具体过程,包括计算hash值、处理碰撞及扩容机制。
|
1月前
|
XML 安全 Java
Java反射机制:解锁代码的无限可能
Java 反射(Reflection)是Java 的特征之一,它允许程序在运行时动态地访问和操作类的信息,包括类的属性、方法和构造函数。 反射机制能够使程序具备更大的灵活性和扩展性
43 5
Java反射机制:解锁代码的无限可能
|
27天前
|
Java 数据库连接 开发者
Java中的异常处理机制及其最佳实践####
在本文中,我们将探讨Java编程语言中的异常处理机制。通过深入分析try-catch语句、throws关键字以及自定义异常的创建与使用,我们旨在揭示如何有效地管理和响应程序运行中的错误和异常情况。此外,本文还将讨论一些最佳实践,以帮助开发者编写更加健壮和易于维护的代码。 ####
|
1月前
|
安全 IDE Java
Java反射Reflect机制详解
Java反射(Reflection)机制是Java语言的重要特性之一,允许程序在运行时动态地获取类的信息,并对类进行操作,如创建实例、调用方法、访问字段等。反射机制极大地提高了Java程序的灵活性和动态性,但也带来了性能和安全方面的挑战。本文将详细介绍Java反射机制的基本概念、常用操作、应用场景以及其优缺点。 ## 基本概念 ### 什么是反射 反射是一种在程序运行时动态获取类的信息,并对类进行操作的机制。通过反射,程序可以在运行时获得类的字段、方法、构造函数等信息,并可以动态调用方法、创建实例和访问字段。 ### 反射的核心类 Java反射机制主要由以下几个类和接口组成,这些类
60 2
|
1月前
|
存储 缓存 安全
🌟Java零基础:深入解析Java序列化机制
【10月更文挑战第20天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
29 3
|
1月前
|
安全 Java UED
深入理解Java中的异常处理机制
【10月更文挑战第25天】在编程世界中,错误和意外是不可避免的。Java作为一种广泛使用的编程语言,其异常处理机制是确保程序健壮性和可靠性的关键。本文通过浅显易懂的语言和实际示例,引导读者了解Java异常处理的基本概念、分类以及如何有效地使用try-catch-finally语句来处理异常情况。我们将从一个简单的例子开始,逐步深入到异常处理的最佳实践,旨在帮助初学者和有经验的开发者更好地掌握这一重要技能。
28 2
|
1月前
|
Java 数据库连接 开发者
Java中的异常处理机制####
本文深入探讨了Java语言中异常处理的核心概念,通过实例解析了try-catch语句的工作原理,并讨论了finally块和throws关键字的使用场景。我们将了解如何在Java程序中有效地管理错误,提高代码的健壮性和可维护性。 ####
|
1月前
|
Java
Java中的反射机制与应用实例
【10月更文挑战第22天】Java作为一门面向对象的编程语言,提供了丰富的特性来支持对象的创建、操作和交互。其中,反射机制是Java的一项核心特性,它允许程序在运行时动态地获取类的信息、创建对象、调用方法、访问属性等。本文将从三个部分探讨Java中的反射机制及其应用实例:一是反射机制的基本概念和原理;二是反射机制在Java中的应用场景;三是通过实例深入理解反射机制的使用方法和技巧。
24 4