反射,枚举和lambda表达式

1. 反射

1. Java 的反射机制

Java 的反射机制是在运行状态,对于任意一个类,都能够直到它所有的属性和方法;

对于任意一个对象,都能调用它的方法和属性;

这种动态获取信息及调用对象方法的功能,称为Java的反射机制;

2. 反射相关的类与方法

Class:代表类的实体,在运行的 Java 程序中表示类和接口;

Field:代表类的成员变量和类的属性;

Method:代表类的方法;

Constructor:代表类的构造方法; 

获得类的相关方法:

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():获得该类所有方法;

3. 反射的使用

 创建 Student 类用于测试:

class Student{//私有属性nameprivate String name = "张三";//公有属性agepublic 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);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

利用反射创建对象,反射私有构造方法,反射私有属性,私有方法:

public class ReflectDemo {public static void testReflect(){try {Class<?> c = Class.forName("Student");// 利用反射创建对象Student student = (Student)c.newInstance();// 利用反射调用私有构造方法Constructor constructor = c.getDeclaredConstructor(String.class, int.class);constructor.setAccessible(true);Student student1 = (Student) constructor.newInstance("lisi", 22);System.out.println(student1);// 利用反射调用私有属性Field field = c.getDeclaredField("name");field.setAccessible(true);field.set(student1, "libai");System.out.println(student1);// 利用反射调用私有方法Method method = c.getDeclaredMethod("eat");method.setAccessible(true);method.invoke(student1);Method function = c.getDeclaredMethod("function", String.class);function.setAccessible(true);function.invoke(student1, "Hello, nice to meet you!");} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}public static void main(String[] args) {ReflectDemo.testReflect();}
}

4. 反射的优缺点

优点:

  • 对于任意一个类,都能知道它的属性和方法;
  • 对于任意一个对象,都能调用它的任意属性和方法;
  • 增加程序的灵活性和扩展性,降低代码的耦合性,提高自适应能力;
  • 反射已经应用在了一些流行框架上,例如 Spring;

缺点:

  • 使用反射会导致程序的效率降低;
  • 反射机制绕过了源代码,反射代码比相应的代码更复杂,因而会有维护问题;

2. 枚举

枚举是将常量组织起来,统一进行管理,常用于表示错误状态码,消息类型,颜色划分,状态机等;

1. 枚举的常用方法

values():以数组形式返回所有成员;

ordinal():获取枚举成员的索引位置;

valueOf():将普通字符转换为枚举实例;

compareTo():比较两个成员在定义时的顺序;

2. 枚举的定义

枚举在 Java 当中实际上就是一个类,在定义枚举的时候,也可以使用构造方法的方式,如下:

public enum TestEnum {RED("red", 0),BLACK("black", 1),GREEN("green", 2),WHITE("white", 3);private String name;private int val;TestEnum(String color, int val){this.name = color;this.val = val;}
}

注意:枚举中的构造方法是私有的;

使用枚举的优缺点:

优点:枚举常量更简单安全,枚举有内置方法,使用枚举,代码更优雅;

缺点:不可继承,无法扩展;

3. 枚举和反射

所有的枚举类都默认继承 java.lang.Enum;

反射包中的 Contructor 类 newInstance() 方法源码如下:

    @CallerSensitivepublic T newInstance(Object ... initargs)throws InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException{if (!override) {if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {Class<?> caller = Reflection.getCallerClass();checkAccess(caller, clazz, null, modifiers);}}if ((clazz.getModifiers() & Modifier.ENUM) != 0)throw new IllegalArgumentException("Cannot reflectively create enum objects");ConstructorAccessor ca = constructorAccessor;   // read volatileif (ca == null) {ca = acquireConstructorAccessor();}@SuppressWarnings("unchecked")T inst = (T) ca.newInstance(initargs);return inst;}

注意到使用反射调用枚举的构造方法就会抛出异常 “Cannot refletively create enum objects ”,因此不能使用反射获取枚举类的实例。

3. Lambda 表达式 

1. 函数式接口

 一个接口有且只有一个抽象方法,这个接口就是一个函数式接口;

如果接口使用 @FunctionalInterface 注解修饰,编译器就会按照函数式接口的格式进行检查,如果里面有多个抽象方法,编译器就会报错;

2. Lambda 表达式的基本使用

Lambda 表达式是匿名内部类的简化,实际上是创建了一个类,实现了接口,重写了接口的方法;

基本语法:(parameters) -> expression 或 (parameters)-> {statements;}

语法精简:

1. 参数类型可以省略,如果需要省略,每个参数的类型都要省略。

2. 参数的小括号里面只有一个参数,那么小括号可以省略

3. 如果方法体当中只有一句代码,那么大括号可以省略

4. 如果方法体中只有一条语句,且是return语句,那么大括号可以省略,且去掉return关键字。

3. 变量的捕获

在匿名内部类中使用类外的变量的时候,要保证变量不会被修改,如果变量被修改了就会报错;

同理,在 lambda 表达式中使用外部的变量也要确保变量不会被修改,如果被修改了也会报错;

4. lambda 表达式的优缺点

优点:

1. 代码简洁,开发迅速

2. 方便函数式编程

3. 非常容易进行并行计算

4. Java 引入 Lambda,改善了集合操作

缺点:

1. 代码可读性变差

2. 在非并行计算中,很多计算未必有传统的 for 性能要高

3. 不容易进行调试

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于 java:8. Java 内存模型与 JVM 基础

一、堆 Java 堆是 JVM 中所有线程共享的运行时内存区域&#xff0c;用于存放所有对象实例、数组以及类的实例字段值。 在 Java 中&#xff1a; String str new String("abc");new String("abc") 创建的对象就分配在堆中。 1.1 堆的特点 特性说明共享…

大语言模型 API 进阶指南:DeepSeek 与 Qwen 的深度应用与封装实践

在昨天小宁已经教大家怎么去获取各个平台的API-kEY,然后也带大家了解了最简单的大模型的调用&#xff0c;那么今天就带大家进阶了解一些更加详细的功能。 在大语言模型的实际应用中&#xff0c;除了基础的问答功能&#xff0c;深度思考能力、推理过程的获取以及灵活的对话模式…

算法与数据结构:解决问题的黄金搭档

1. 算法的定义 算法&#xff08;Algorithm&#xff09; 是解决特定问题的精确步骤序列&#xff0c;本质是“解决问题的方法论”。 核心特征&#xff1a; 输入&#xff1a;接受数据&#xff08;如零个、多个参数&#xff09;。输出&#xff1a;必须产生明确结果&#xff08;如…

【MySQL】JDBC编程

MySQL(七)JDBC编程 一、驱动包 1.性质 1.1底层差异性 1.2JDBC接口统一性 2.导入 2.1复制导包 2.2标记作库 二、JDBC编程 1.寻找资源 1.1URL 1.1.1网址作用 1.1.2主机IP 1.1.3端口号 1.1.4数据库名 1.1.5访问资源参数 2.访问认证 2.1身份 2.2密码 3.连接通道…

RAG 架构地基工程-Retrieval 模块的系统设计分享

目录 一、知识注入的关键前奏——RAG 系统中的检索综述 &#xff08;一&#xff09;模块定位&#xff1a;连接语言模型与知识世界的桥梁 &#xff08;二&#xff09;核心任务&#xff1a;四大关键问题的协调解法 &#xff08;三&#xff09;系统特征&#xff1a;性能、精度…

浅谈AI大模型-MCP

MCP简介 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议 &#xff09;&#xff0c;24年11月初的时候Anthropic发了一篇技术博客&#xff0c;推出了他们的模型上下文协议MCP&#xff0c;介绍了一种规范&#xff1a;应用如何为LLM提供上下文。官网称MCP为AI应…

ROS常用的路径规划算法介绍

在ROS中&#xff0c;常用的路径规划算法主要有以下几种&#xff1a; 全局路径规划算法 A*算法&#xff1a;在Dijkstra算法基础上加入启发式函数&#xff0c;如曼哈顿距离或欧氏距离&#xff0c;优先探索靠近目标的节点&#xff0c;效率更高。需使用可容许的启发式函数以保证最…

基于springboot+vue的数字科技风险报告管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.3.9 系统展示 管理员登录 管理…

docker compose基本使用以及示例

一、docker-compose模板文件 字段含义build指定Dockerfile所在的文件夹路径image指定为镜像名称或镜像IDcontainer_name指定容器模式depends_on指定多个服务之间的依赖关系ports端口映射command覆盖容器启动后默认执行的命令entrypoint覆盖容器中默认的入口命令env_file从文件…

开源3D 动态银河系特效:Vue 与 THREE.JS 的奇幻之旅

一、Vue 与 THREE.JS 简介 &#xff08;一&#xff09;Vue Vue 是一个流行的 JavaScript 框架&#xff0c;它采用了组件化的设计思想&#xff0c;使得开发人员可以轻松地构建复杂的用户界面。Vue 提供了丰富的功能和工具&#xff0c;如数据绑定、指令、组件通信等&#xff0c…

EXISTS 和 NOT EXISTS 、IN (和 NOT IN)

在 SQL 中&#xff0c;EXISTS、NOT EXISTS 和 IN 都是用于子查询的条件运算符&#xff0c;用于根据子查询的结果过滤主查询的行。它们之间的区别主要体现在工作方式、效率、对 NULL 值的处理以及适用场景上。 1. EXISTS 和 NOT EXISTS 作用&#xff1a; EXISTS: 检查子查询是…

医疗标准集中标准化存储与人工智能智能更新协同路径研究(上)

摘要 为了提高医疗系统中文件管理的效率与质量,本文围绕医疗文档的集中化标准化存储与人工智能驱动的智能更新,构建了一种协同策略研究框架。通过分析医疗文档管理的痛点,结合集中化存储与AI技术的协同路径,提出了一种基于标准化文档处理与智能更新的协同优化方案。研究发现…