【数据结构】(12) 反射、枚举、lambda 表达式

news2025/2/28 22:24:19

一、反射

1、反射机制定义及作用

        反射是允许程序在运行时检查和操作类、方法、属性等的机制,能够动态地获取信息、调用方法等。换句话说,在编写程序时,不需要知道要操作的类的具体信息,而是在程序运行时获取和使用。

2、反射机制的原理

        程序运行时,JVM编译好的 .class 文件(代表一个类)解析为 java.lang.Class 类的实例,这个实例包含了该类的所有信息。通过反射机制,可以用到这个实例,来获取该类的信息并进行操作

        下面介绍反射的相关类。以 Student 类为例子:

public class Student {
    //私有属性name
    private String name = "小帅";
    //公有属性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 在 java.lang 中,不需要导包。其它三个都在 java.lang.reflect 中。

3、Class 类

        代表类的实体

        获取 JVM 给类解析的 Class 对象:

        其它方法:

4、Field 类

        代表类的属性

  • getField(String name):获得指定公有属性对象。
  • getField():获得所有公有属性对象。
  • getDeclaredField(String name):获得某个属性对象。(不限于公有)
  • getDeclaredField():获得所有属性对象。

        属性对象.get(对象) 表示获取指定对象的某属性,静态属性不需对象,参数填 null。

5、Method 类

        代表类的方法

6、Constructor 类

        代表类的构造方法

        利用构造方法对象获得类的实例:

7、使用反射动态加载类并创建对象

        编写一个程序,在运行时根据用户输入的类名来动态加载类并创建对象,调用其 draw 方法。

import java.util.Scanner;

// 定义一个 Shape 接口
interface Shape {
    void draw();
}

// 定义 Circle 类实现 Shape 接口
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制一个圆形");
    }
}

// 定义 Rectangle 类实现 Shape 接口
class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制一个矩形");
    }
}

public class DynamicClassLoadingExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要加载的类名(如 Circle 或 Rectangle):");
        String className = scanner.nextLine();

        try {
            // 根据用户输入的类名获取 Class 对象
            Class<?> clazz = Class.forName(className);
            // 创建该类的实例
            Shape shape = (Shape) clazz.getDeclaredConstructor().newInstance();
            // 调用 draw 方法
            shape.draw();
        } catch (Exception e) {
            e.printStackTrace();
        }
        scanner.close();
    }
}

反射优点:让程序更灵活,动态加载类和方法、可以访问和修改私有成员。

反射缺点:性能开销大、破坏封装性和安全性、程序不易读。

二、枚举

1、定义及作用

        一组常量,比如颜色,它们是同一类,我们想把这组常量组织在一起,就用枚举。作用是与没有意义的数字区分开来(如果定义一组常量,就要用数字表示它们)。例子:

public enum Color {
    RED, GREEN, BLUE;
    public static void main(String[] args) {
        Color color = Color.BLUE;
        switch (color) {
            case RED:
                System.out.println("RED");
                break;
            case GREEN:
                System.out.println("GREEN");
                break;
            case BLUE:
                System.out.println("BLUE");
                break;
            default:
                System.out.println("default");
                break;
        }
    }
}

        枚举类默认继承了 java.lang.Enum。枚举常量的默认是 public static final 修饰

2、常用方法

        枚举类型能够使用这些方法,是因为默认继承了 Enum 类:

        但是可以发现,Enum 类中没有 values 方法。这是因为自定义枚举类型中枚举常量的数量、类型都是不确定的,如果 values 封装在 Enum 类中,就需要在运行时动态确定每个枚举常量(需要用到反射,破坏了封装性、增强了复杂性等)。实际上,编译器编译时会为每个枚举类型自动加上 values 方法,返回的数组在编译时就确定

3、构造方法

        枚举相当于是类,可以有属性、构造方法、方法。构造方法默认私有,且只能。这样保证了枚举实例的唯一性。

 查看构造函数的实际参数有哪些:

        多了 String 和 int 类型参数,因为枚举类默认继承了 Enum,其本身有 name 和 ordinal 属性,隐藏了 super(name, ordinal) ,所以 Color 构造函数会多 2 个参数

4、枚举和反射

        通过反射获取枚举类的实例:

         出现错误:

       查看 newInstance 源码:

        因此,不能通过反射创建枚举类的实例。这样设计的目的是让枚举类只有一个实例防止反射攻击由私有构造函数、防反射攻击这两个特点得知,枚举实现单例模式(一种创建型模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例)是安全的

枚举优点:简单安全。

枚举缺点:不能继承

5、枚举实现单例模式

        后续学了单例模式补充。

三、Lambda 表达式

1、定义及作用

        相当于方法,但是比方法更简化。语法:

(形参列表)->表达式

(形参列表)->{代码块}

// 参数类型可以省略(要省全都省),只有一个参数可以省略圆括号。

// 返回一个值或者不返回值

// 只有一条 return 语句,可省略 return

2、函数式接口

  • 函数式接口:一个接口只有一个抽象方法
  • @FunctionalInterface 注解:以函数式接口的标准(只有一个抽象方法)要求接口,检查作用。
  • lambda 可简化匿名内部,实现函数式接口

        几个函数式接口代码:

//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
    void test();
}

        使用匿名内部类实现接口,重写方法:

        使用 lambda 实现接口,重写方法:

NoParameterNoReturn noParameterNoReturn = ()->{System.out.println("hello");};

3、变量捕获

        匿名内部类中可捕获外部变量。如果想修改捕获的变量,那该变量必须被 final 修饰,否则报错。lambda 表达式同理

        int a = 10;
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
//                a = 99;  不允许修改未被 final 修饰的外部变量
                System.out.println(a); // 变量 a 捕获
                return o1.compareTo(o2);
            }
        });

4、Lambda 在集合中的应用

        lambda 表达式作为以上方法的参数,实现接口中的方法。 

4.1、Collection 接口

        以 forEach 为例:

        源码如下:Consumer 是函数式接口,accept 是实现的抽象方法。

        实现函数式接口:

4.2、List 接口

        以 sort 为例:

        源码:

        在 Java 中,所有类都直接或间接地继承自 Object 类,因此,Comparator 接口继承了 Object 类的 equals 方法。它不是 Comparator 接口自身定义的抽象方法,因此,不违反函数式接口的定义规则。

    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);

        boolean equals(Object obj); // 继承自 Object,不影响函数式接口
        
        ......
    }

        实现:

4.3、Map 接口

        以 forEach 为例:

        源码:

        实现:

5、总结:

优点:语句简洁、方便函数式编程(替换匿名内部类)、改善集合操作。

缺点:可读性差、不易调试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2307585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ONES 功能上新|ONES Copilot、ONES Project 新功能一览

ONES Copilot 智能 AI 助手模型可配置多种类型模型&#xff0c;服务提供方 Dashscope 的模型列表中新增 DeepSeek V3 与 DeepSeek R1&#xff1b;选择自定义模型配置时&#xff0c;填写私有部署的 DeepSeek 模型相关参数即可。 应用场景&#xff1a; 企业内部自部署或在模型服务…

STM32寄存器控制引脚高低电平

一. 引子 最近在学习32代码的过程当中&#xff0c;虽然在学习IMX6ULL开发板的过程中接触过很多寄存器&#xff0c;最近在返回去看32的时候&#xff0c;在研究代码的时候发现自己对于寄存器的有些特性理解的不够深刻&#xff0c;所以下来的时候去查了资料&#xff0c;以及问了一…

SOC-ATF 安全启动BL1流程分析(1)

一、ATF 源码下载链接 1. ARM Trusted Firmware (ATF) 官方 GitHub 仓库 GitHub 地址: https://github.com/ARM-software/arm-trusted-firmware 这是 ATF 的官方源码仓库&#xff0c;包含最新的代码、文档和示例。 下载方式&#xff1a; 使用 Git 克隆仓库&#xff1a; git…

TDesign:Cascader 级联选择器(省市区三级联动)

Cascader 级联选择器API 参考官方示例代码 在自己的模板中使用&#xff1a;view import package:ducafe_ui_core/ducafe_ui_core.dart; import package:flutter/material.dart; import package:get/get.dart; import package:tdesign_flutter/tdesign_flutter.dart;import i…

linux中安装部署Jenkins,成功构建springboot项目详细教程

参考别人配置Jenkins的git地址为https&#xff0c;无法连上github拉取项目&#xff0c;所以本章节介绍通过配置SSH地址来连github拉取项目 目录&#xff1a; 1、springboot项目 1.1 创建名为springcloudproject的springboot项目工程 1.2 已将工程上传到github中&#xff0c;g…

2025系统架构师(一考就过):案例之四:架构复用、架构评估、特定架构(DSSA)、架构开发方法(ABSD)

二、软件架构复用 ◆软件产品线是指一组软件密集型系统&#xff0c;它们共享一个公共的、可管理的特性集&#xff0c;满足某个特定市场或任务的具体需要&#xff0c;是以规定的方式用公共的核心资产集成开发出来的。即围绕核心资产库进行管理复用、集成新的系统。 ◆软件架构…

基于定制开发开源AI大模型S2B2C商城小程序的商品选品策略研究

摘要&#xff1a;随着电子商务的蓬勃发展和技术的不断进步&#xff0c;商品选品在电商领域中的重要性日益凸显。特别是在定制开发开源AI大模型S2B2C商城小程序的环境下&#xff0c;如何精准、高效地选择推广商品&#xff0c;成为商家面临的一大挑战。本文首先分析了商品选品的基…

Docker 2025/2/24

用来快速构建、运行和管理应用的工具。帮助部署。 快速入门 代码略 解释 docker run :创建并运行一个容器&#xff0c;-d是让容器在后台运行 --name mysql :给容器起个名字&#xff0c;必须唯一 -p 3306:3306 :设置端口映射 -e KEYVALUE :是设置环境变量 mysql :指定运行的…

爱普生SG-8101CE可编程晶振赋能智能手机的精准心脏

在智能手机高速迭代的今天&#xff0c;高性能、低功耗与小型化已成为核心诉求。智能手机作为人们生活中不可或缺的工具&#xff0c;需要在各种复杂场景下稳定运行。爱普生SG-8101CE可编程晶振凭借其卓越性能&#xff0c;成为智能手机中不可或缺的精密时钟源&#xff0c;为通信、…

StableDiffusion打包 项目迁移 项目分发 1

文章目录 SD项目迁移前置知识webui-user.batwebui.batlaunch_utils.py 下一篇开始实践 SD项目迁移 显卡驱动更新&#xff1a;https://www.nvidia.cn/geforce/drivers/ 下载安装三个程序&#xff1a; python3.10.6: https://www.python.org/downloads/release/python-3106/gi…

【数据结构进阶】哈希表

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 一、哈希表的概念 二、哈希函数的实现方法 1. 直接定址法 2. 除留余数法 三、哈希冲突 1. 开放定址法&#xff08;闭散列&#xff0…

【蓝桥杯嵌入式】各模块学习总结

系列文章目录 留空 文章目录 系列文章目录前言一、LED模块1.1 赛题要求1.2 模块原理图1.3 编写代码1.4 赛题实战 二、LCD模块2.1 赛题要求2.2 模块原理图2.3 编写代码2.4 赛题实战 三、按键模块3.1 赛题要求3.2 模块原理图3.3 编写代码3.4 赛题实战 四、串口模块4.1 赛题要求4…

Rust学习总结之-枚举

枚举是一个很多语言都有的功能&#xff0c;不过不同语言中其功能各不相同但是要表达的意思是一致的&#xff0c;枚举就是对于一个事物可以穷举出所有可能得值。比如说人的性别就可以用枚举&#xff0c;男人和女人两种。下面我们来学习Rust中的枚举。 一&#xff1a;枚举定义 …

Linux系统管理(十七)——配置英伟达驱动、Cuda、cudnn、Conda、Pytorch、Pycharm等Python深度学习环境

文章目录 前言安装驱动下载安装Cuda编辑环境变量安装Cudnn安装conda验证安装成功配置conda镜像退出conda环境创建python环境查看当前conda环境激活环境安装python包安装pytorch 安装pycharm安装jupyter notebook 前言 深度学习和大语言模型的部署不免会用到Linux系统&#xff…

SLAM算法工程师的技术图谱和学习路径

SLAM(Simultaneous Localization and Mapping)算法工程师是负责开发和实现用于机器人、自动驾驶车辆等领域的SLAM算法的专业人士。下面是SLAM算法工程师需要掌握的基础理论知识: 机器人运动学和动力学:理解机器人在空间中的运动方式和控制方法,包括轮式、蜘蛛腿、飞行器等…

深入了解 Python 中的 MRO(方法解析顺序)

文章目录 深入了解 Python 中的 MRO&#xff08;方法解析顺序&#xff09;什么是 MRO&#xff1f;如何计算 MRO&#xff1f;C3 算法的合并规则C3 算法的合并步骤示例&#xff1a;合并过程解析 MRO 解析失败的场景使用 mro() 方法查看 MRO示例 1&#xff1a;基本用法 菱形继承与…

如何防止 Instagram 账号被盗用:安全设置与注意事项

如何防止 Instagram 账号被盗用&#xff1a;安全设置与注意事项 在这个数字化时代&#xff0c;社交媒体平台如 Instagram 已成为我们日常生活的一部分。然而&#xff0c;随着网络犯罪的增加&#xff0c;保护我们的在线账户安全变得尤为重要。以下是一些关键的安全设置和注意事…

采样算法二:去噪扩散隐式模型(DDIM)采样算法详解教程

参考 https://arxiv.org/pdf/2010.02502 一、背景与动机 去噪扩散隐式模型&#xff08;DDIM&#xff09; 是对DDPM的改进&#xff0c;旨在加速采样过程同时保持生成质量。DDPM虽然生成效果优异&#xff0c;但其采样需迭代数百至数千次&#xff0c;效率较低。DDIM通过以下关键…

各种类型网络安全竞赛有哪些 网络安全大赛的简称

本文是对入门学习的一些概念了解和一些常规场景记录 1.CTF&#xff08;capture the flag&#xff09;是夺旗赛的意思。 是网络安全技术人员之间进行攻防的比赛。 起源1996年DEFCON全球黑客大会&#xff0c;替代之前真实攻击的技术比拼。 (DEFCON极客大会诞生1993&#xff0c;…

包子凑数——蓝桥杯真题Python

包子凑数 输入输出样例 示例 1 输入 2 4 5输出 6样例说明 凑不出的数目包括&#xff1a;1, 2, 3, 6, 7, 11。 示例 2 输入 2 4 6输出 INF样例说明 所有奇数都凑不出来&#xff0c;所以有无限多个 运行限制 最大运行时间&#xff1a;1s最大运行内存: 256M 最大公约数 最大公…