Java零基础入门-Java反射机制

一、概述

我们都听说过java有个反射机制,通过反射机制我们可以更深入的控制程序的运行过程。例如,在程序进入到运行期间,由用户输入一个类名,然后我们可以动态获取到该类拥有的所有类结构、属性名和方法,甚至还可以任意调用类的任意方法。听起来是不是很牛?我也觉得比较牛,挺有意思的,所以对于不太熟悉的小伙伴而言,那就来听我一一道来。

所以此期我们就来重点学习一下java的反射机制。

二、本期教学目标

  • 了解什么是反射?
  • 了解反射的优缺点
  • 熟悉通过反射获取java对象的方法
  • java常用的反射机制api
  • java通过反射执行方法
  • 反射实例演示

三、正文

本文首先介绍一下java中class类与java反射的基础用法,然后再结合应用具体介绍反射。

1️⃣概念

什么是反射?在介绍反射之前,我们先来了解两个概念,编译器和运行期。

  1. 编译器:编译器是把源代码交给编译器编译成计算机可执行的字节码文件的过程。
  2. 运行期:运行期是把编译好的字节码文件交给计算机(在内存)去执行的过程,直到运行结束。

而java反射,就是在程序处于运行状态中,对于任意一个类,都能够动态的获取到这个类的所有属性、方法;对于任意一个对象,都能调用它的任意方法和内部属性。这种动态获取信息以及动态调用对象方法属性的功能就被成为java的反射机制。总而言之,java反射指的是程序在运行时能获取自身的所有信息,比如类名、类路径、包路径、构造方法、私有属性等等。

所以对于java程序,只要你给定一个类名,你就可以通过java反射获取到该类的所有信息。

2️⃣功能

对于java反射机制而言,它主要提供了以下功能,且这些功能都位于java.lang.reflect包中。

如下是对于程序中,该reflect截图。

如下我就给大家诺列以下:

  • 获取任意一个对象所属的类(运行期)
  • 构造任意一个类的对象(运行期)
  • 判断任意一个类所具有的成员变量和方法(运行期)
  • 调用任意一个对象的方法(运行期)
  • 生成动态代理。

而想要知道一个类的属性和方法,你必须先获取到该类的字节码文件对象。获取类信息时,使用的就是class类的方法。所以你先要获取到每一个字节码文件对应的class类型对象。比如:

java 复制代码
 Class aClass = dog1.getClass();

3️⃣常用Api

利用class类的对象aClass可以获取到的该类的所有信息,比如类信息、Object信息。如下是列举出来的是通过反射可获取到的常用信息,具体如下:

  • getPackage():获取该类的存放路径。
  • getName():获取该类的名称。
  • getSuperclass():获取该类继承的类
  • getlnterfaces():获取该类实现的所有接口
  • getMethods():获取所有权限为 public 的方法
  • getDeclaredMethods():获取当前对象的所有方法
  • getClasses():获取所有权限为 public 的内部类
  • getFields():获取所有权限为 public 的成员变量

4️⃣优缺点

对于反射,虽然利大于弊,但是不排除任意一个东西开发出来,都没有任何缺点。比如对于java的反射机制。

  • 优点:能够程序运行时动态获取类的实例,大大提高了系统的灵活性和扩展性。且对于java先编译后运行的机制而言,更加方便灵活创建代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加的贴切面向对象。
  • 缺点:反射会消耗一定的系统资源。因此如果不需要动态的创建一个对象,那就不需要使用反射。而且通过反射手法,在调用对象方法时可以忽略权限检查就能获取到该类的私有属性私有方法,可能会导致破坏类的封装性而导致安全问题。

5️⃣实例演示

如下我就通过列举一个类通过实例化后来通过反射机制来动态获取该对象的一些信息。

具体演示代码如下:

java 复制代码
@Data
public class Dog extends Animal {//子类

    private String active;

    @Override
    public void eat() {
        System.out.println("我是狗狗,吃骨头!");
    }

    //独有功能
    public void lockHome() {
        System.out.println("我是狗狗,我会看家");
    }
}

然后我再来定义一个main函数进行测试获取一下该对象名称:

java 复制代码
    public static void main(String[] args) {

        Animal dog = new Dog();//向上转型

        Class dogClass = dog.getClass();
        System.out.println("该类的名称为:"+dogClass.getName());
    }

运行截图如下:

获取该dog对象包名:

java 复制代码
    public static void main(String[] args) {

        Animal dog = new Dog();//向上转型

        Class dogClass = dog.getClass();
        System.out.println("该类的包名为:"+dogClass.getPackage());
    }

运行截图如下:

获取该dog对象的所有方法。

java 复制代码
    public static void main(String[] args) {

        Animal dog = new Dog();//向上转型

        Class dogClass = dog.getClass();
        Method[] methods = dogClass.getDeclaredMethods();
        System.out.println("该类的所有方法为:"+methods);
    }

运行截图如下:

获取所有权限为 public 的内部类。

java 复制代码
    public static void main(String[] args) {

        Animal dog = new Dog();//向上转型

        Class dogClass = dog.getClass();
        Class[] classes = dogClass.getClasses();
        System.out.println("获取所有权限为public 的内部类:" + classes);
    }

运行截图如下:

相关推荐
量化炼金 (CodeAlchemy)2 分钟前
【Python】pandas vs polars 简单性能对比测试
开发语言·python·pandas
苦瓜汤补钙3 分钟前
Matlab 2022b(中文)的使用教程——Win11
开发语言·matlab
Ai-_Man3 分钟前
我需要批量导出Poe左边栏所有对话,而不是一条具体的对话内容,你们AI导出鸭可以吗?
开发语言·前端·javascript·人工智能·小程序
福大大架构师每日一题6 分钟前
rust 1.99.1 正式更新:聚焦 UEFI、嵌入式、x86_64 FFI 与 macOS 链接体验的三项修复
开发语言·macos·rust
Pin_Qing10 分钟前
缓存能活多久,现在是个要算的参数
java·大数据·开发语言·人工智能·程序人生
小道士写程序11 分钟前
Rust 元组详解:复合类型的基础
开发语言·rust
jyOverQ14 分钟前
从零开始学 RocketMQ(四):集群部署、消息存储与高可用【保姆级教程】
java·rocketmq·java-rocketmq
小裕哥略帅20 分钟前
行级数据权限控制@DataPermission
java·开发语言
ZoeLandia26 分钟前
React05:useEffect 与副作用
开发语言·前端·react.js·typescript
ManageEngineITSM27 分钟前
ITSM系统如何与企业微信、钉钉、飞书集成?提升工单处理效率的方法
java·大数据·开发语言·钉钉·企业微信·变更管理