JAVA基础 反射技术学习笔记 1

简介: JAVA基础 反射技术学习笔记

一、反射机制介绍

网络异常,图片无法展示
|

1.1 什么是反射

Java 反射机制是Java语言一个很重要的特性,它使得Java具有了“动态性”。在Java程序运行时,对于任意的一个类,我们能不能知道这个类有哪些属性和方法呢?对于任意的一个对象,我们又能不能调用它任意的方法?答案是肯定的!这种动态获取类的信息以及动态调用对象方法的功能就来自于Java 语言的反射(Reflection)机制。


编程语言分为动态语言和非动态语言,动态语言指的是在程序运行时可以改变程序的结构或者变量的类型,常见的python、JavaScript等。Javav不是动态语言,但是反射机制的存在使得Java具有多态性,或者说Java具有”半多态性“。

1.2 反射的作用

简单来说两个作用,RTTI(运行时类型识别)和DC(动态创建)。


我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!

二、创建对象过程分析

实例化一个对象时,JVM虚拟机会先去磁盘中把该类的字节文件(xxx.class文件)通过IO的形式加载到虚拟机的内存中,加载到内存后会根据字节文件形成class对象(这个class对象不是class类的实例,而是class字节文件的对象类型),该class类对象包含该类的所有信息,包括属性、成员变量、构造方法、成员方法等(也就是说字节文件对象中也和普通的类对象一样有成员变量,成员方法和构造方法等,但是和普通类对象不同的是,普通类的成员变量可能是基本数据类型或者是引用类型、其他对象类型等,但是字节文件对象的成员变量的数据类型就是成员变量对象类型或者说是成员变量类型(因为一个成员变量包含访问修饰符,变量名称和值等,这些元素构成了成员变量对象),以此类推类中的构造方法也会存放到字节文件对象的构造方法对象类型的变量中……);然后再将class对象中的成员变量在堆中进行初始化,此时才算是创建了个对象。


需要注意的是无论该类被实例化多少次,JVM的类加载器只会对该类加载一次到虚拟内存,并且在虚拟内存中缓存。每new一次JVM将成员变量在堆中初始化一次。

创建对象时内存结构

Users user = new Users();

实际上,我们在加载任何一个类时都会在方法区中建立“这个类对应的Class对象”,由于“Class对象”包含了这个类的整个结构信息,所以我们可以通过这个“Class对象”来操作这个类。


我们要使用一个类,首先要加载类;加载完类之后,在堆内存中,就产生了一个 Class 类型的对象(一个类只有一个 Class 对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象知道类的结构。这个对象就像一面镜子,透过这个镜子可以看到类的结构,所以,我们形象的称之为:反射。 因此,“Class对象”是反射机制的核心。

三、获取class字节文件对象(类对象)的三种方式

3.1 通过getClass();方法获取类的字节文件对象

package cn.it.bz.Reflect;
public class GetClass1 {
    public static void main(String[] args) {
        //通过getClass();方法获取类的字节文件对象
        User user = new User();
        Class aClass = user.getClass();
        System.out.println(aClass);//调用Class类的toString方法
        String name = aClass.getName(); //获取User类的全名
        System.out.println(name);
        User user1 = new User();
        System.out.println(aClass == user1.getClass());//true,证明类字节文件对象只有一份
    }
}

需要注意的是,new对象之后JVM会在将对类的字节文件对象加载到内存的方法区中。说明此时在JVM虚拟内存中已经存在了User类的字节文件对象。

3.2 通过.class 静态属性获取Class对象

package cn.it.bz.Reflect;
//通过.class 静态属性获取Class对象
public class GetClass2 {
    public static void main(String[] args) {
         Class<User> userClass = User.class;
         Class<User> userClass1 = User.class;
        System.out.println(userClass == userClass1);//true
    }
}

当调用User.class时,如果JVM虚拟内存中存在User类的字节文件对象,则直接返回该字节文件对象。如果JVM虚拟内存不存在该字节文件对象,则会JVM会创建User类的字节文件对象加载到虚拟内存。

3.3 通过forName()获取Class对象

package cn.it.bz.Reflect;
public class GetClass3 {
    public static void main(String[] args) throws ClassNotFoundException {
       Class aClass = Class.forName("cn.it.bz.Reflect.User");//该方法是Class类下的静态方法,参数是类的全名
        System.out.println(aClass);
    }
}

当调用forName方法时,JVM先从虚拟内存中找有没有该类对应的字节文件对象,有就直接拿出来,没有就使用类加载器将该类加载到虚拟内存中。

四、通过字节文件对象获取类的信息

4.1 获取类的构造方法

image.png

package cn.it.bz.Reflect;
public class User {
    private String name;
    private int age;
    public User() {
    }
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    private User(String name) {
        this.name = name;
    }
    private User(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
package cn.it.bz.Reflect;
import java.lang.reflect.Constructor;
public class GetConstructor {
    public static void main(String[] args) throws NoSuchMethodException {
        //获取类字节文件对象
        Class userClass = User.class;
        //获取类的全部构造方法,忽略访问控制符
        Constructor[] declaredConstructors = userClass.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        System.out.println("----------------");
        //获取全部的被public修饰的访问控制符
        Constructor[] constructors = userClass.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("---------------");
        //获取参数是int类型的构造方法忽略访问控制符,int.class实际上就是Integer.class
        Constructor declaredConstructor = userClass.getDeclaredConstructor(int.class);
        System.out.println(declaredConstructor);
        System.out.println("----------------");
        //获取无参数的public修饰的构造方法
        Constructor constructor = userClass.getConstructor();
        System.out.println(constructor);
    }
}

4.2 通过类的构造方法实例化对象

package cn.it.bz.Reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class GetConstructor2 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取User类的字节文件对象
        Class<User> userClass = User.class;
        //获取类的构造方法对象
        Constructor<User> constructor = userClass.getConstructor(String.class, int.class);
        //通过构造方法实例化类对象
        User user = constructor.newInstance("张三", 18);
        System.out.println(user);
    }
}


相关文章
|
1月前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
66 11
|
1月前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
71 7
|
27天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
13天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
25天前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
1月前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
监控 Java
Java基础——反射
本文介绍了Java反射机制的基本概念和使用方法,包括`Class`类的使用、动态加载类、获取方法和成员变量信息、方法反射操作、以及通过反射了解集合泛型的本质。同时,文章还探讨了动态代理的概念及其应用,通过实例展示了如何利用动态代理实现面向切面编程(AOP),例如为方法执行添加性能监控。
|
2月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
2月前
|
JSON 前端开发 JavaScript
java-ajax技术详解!!!
本文介绍了Ajax技术及其工作原理,包括其核心XMLHttpRequest对象的属性和方法。Ajax通过异步通信技术,实现在不重新加载整个页面的情况下更新部分网页内容。文章还详细描述了使用原生JavaScript实现Ajax的基本步骤,以及利用jQuery简化Ajax操作的方法。最后,介绍了JSON作为轻量级数据交换格式在Ajax应用中的使用,包括Java中JSON与对象的相互转换。
64 1
|
2月前
|
SQL 监控 Java
技术前沿:Java连接池技术的最新发展与应用
本文探讨了Java连接池技术的最新发展与应用,包括高性能与低延迟、智能化管理和监控、扩展性与兼容性等方面。同时,结合最佳实践,介绍了如何选择合适的连接池库、合理配置参数、使用监控工具及优化数据库操作,为开发者提供了一份详尽的技术指南。
48 7