Java bs架构/反射

bs架构

规定的格式是要换行,而打印流天然换行 

 线程池可以直接处理thread,thread继承自runnable

在Java中,线程池的pool.execute()方法用于提交一个任务给线程池执行。这个方法接受一个Runnable对象作为参数。Runnable是一个函数式接口,因此你可以直接传递一个实现了Runnable接口的类的实例,或者使用lambda表达式。

所以,pool.execute()里面填的是Runnable类型。

例如:

java

复制

// 使用匿名内部类
pool.execute(new Runnable() {@Overridepublic void run() {// 任务执行的代码}
});// 使用lambda表达式
pool.execute(() -> {// 任务执行的代码
});

在Java 8及更高版本中,还可以使用方法引用。如果有一个已经定义好的方法,其签名与Runnablerun方法相匹配,可以直接使用方法引用。

例如:

java

复制

// 假设有一个方法叫做taskMethod,它没有参数且返回void
pool.execute(this::taskMethod);

这里的this::taskMethod就是方法引用,表示将taskMethod方法作为Runnablerun方法执行。

需要注意的是,pool.execute()方法不会返回任何结果。如果你需要任务执行完成后返回一个结果,应该使用pool.submit()方法,它接受一个Callable<T>对象作为参数,并返回一个Future<T>对象,用于获取任务执行的结果。、

thread runnable

在Java中,ThreadRunnable都是用于实现多线程的机制,但它们之间有一些关键的区别和联系:

  1. Thread类

    • Thread是一个类,它直接实现了Runnable接口。
    • 你可以创建一个Thread的子类并覆盖它的run方法来定义线程的行为。
    • Thread对象表示一个线程的执行实例。

    示例:

    java

    复制

    public class MyThread extends Thread {@Overridepublic void run() {// 线程执行的代码}
    }MyThread myThread = new MyThread();
    myThread.start(); // 启动线程
    
  2. Runnable接口

    • Runnable是一个函数式接口,它只有一个方法:run
    • 你可以实现Runnable接口并定义run方法来创建一个线程任务。
    • Runnable本身并不表示一个线程,而是线程执行的任务。

    示例:

    java

    复制

    public class MyRunnable implements Runnable {@Overridepublic void run() {// 线程执行的代码}
    }Thread thread = new Thread(new MyRunnable());
    thread.start(); // 启动线程
    

关系

  • 实现方式Thread类实现了Runnable接口,这意味着每个Thread对象都是一个Runnable
  • 多态性:你可以将一个Runnable对象传递给Thread的构造函数,这样Thread就会执行Runnable中的run方法。
  • 灵活性:通过实现Runnable接口,你可以将线程的行为与线程的创建分离,这样可以在多个线程中共享相同的任务代码,提高代码的复用性。

使用场景

  • 当你想要自定义线程的行为并且不需要继承其他类时,可以继承Thread类。
  • 当你想要多个线程共享相同的任务代码,或者需要继承其他类时,可以实现Runnable接口。

启动线程

无论你使用Thread子类还是Runnable实现,都需要创建一个Thread对象并调用它的start方法来启动线程。start方法会调用run方法,但start会在新线程中执行run,而直接调用run则会在当前线程中执行。

总结

  • Thread是线程的执行实例,可以独立运行。
  • Runnable是线程执行的任务,需要通过Thread来运行。
  • Thread类实现了Runnable接口,提供了线程的创建和启动机制。
  • Runnable接口允许你定义线程的任务,但不直接创建线程。

反射获取成员方法

在Java中,使用反射API可以获取类的成员方法(Method),包括构造方法、公共方法、受保护方法、默认(包)访问方法和私有方法。以下是如何使用反射获取成员方法以及参数说明:

获取成员方法

要获取类的成员方法,你需要使用Class类提供的getMethodgetMethods方法。getMethod用于获取指定的公共成员方法,而getMethods用于获取所有公共成员方法。如果你想要获取包括私有和受保护方法在内的所有方法,可以使用getDeclaredMethodgetDeclaredMethods

Method类

Method类对象代表一个方法,它提供了用于获取方法信息的方法,如方法名、返回类型、参数类型等,以及用于调用方法的方法。

参数说明

以下是使用反射获取成员方法时常用的一些方法和参数说明:

  • Class<?> getDeclaringClass()

    • 返回表示声明该方法的类或接口的Class对象。
  • String getName()

    • 返回方法名。
  • int getModifiers()

    • 返回方法的修饰符,如publicprivatestatic等,返回值可以用于Modifier类的方法来分析。
  • Class<?> getReturnType()

    • 返回方法的返回类型。
  • Class<?>[] getParameterTypes()

    • 返回一个数组,包含方法的参数类型。
  • Class<?>[] getExceptionTypes()

    • 返回一个数组,包含方法抛出的异常类型。
  • Object invoke(Object obj, Object... args)

    • 在具有指定参数的指定对象上调用此Method对象表示的基础方法。
    • obj:从其上调用基础方法的对象(如果方法是静态的,则可以是null)。
    • args:用于方法调用的参数(如果方法没有参数,则可以是null)。

示例代码

以下是一个使用反射获取并调用成员方法的示例:

java

复制

import java.lang.reflect.Method;public class ReflectionExample {public static void main(String[] args) {try {// 获取Class对象Class<?> cls = Class.forName("java.lang.String");// 获取所有公共成员方法Method[] methods = cls.getMethods();// 遍历并打印方法信息for (Method method : methods) {System.out.println("方法名: " + method.getName());System.out.println("返回类型: " + method.getReturnType());System.out.println("参数类型: ");Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("  " + parameterType);}System.out.println("--------------------");}// 获取并调用指定的公共成员方法Method substringMethod = cls.getMethod("substring", int.class, int.class);String result = (String) substringMethod.invoke("Hello, World!", 7, 12);System.out.println("调用结果: " + result);} catch (Exception e) {e.printStackTrace();}}
}

在这个示例中,我们首先获取了String类的Class对象,然后获取并打印了所有公共成员方法的信息。接着,我们获取了substring方法,并使用invoke方法调用了它,传递了字符串 "Hello, World!" 和两个整数参数 7 和 12

请注意,使用反射时可能会遇到各种异常,如ClassNotFoundExceptionNoSuchMethodExceptionIllegalAccessExceptionInvocationTargetException,因此需要适当地处理这些异常。

getDeclaredMethod 

是 Java 反射 API 中 Class 类的一个方法,用于获取类中声明的方法,包括公共、保护、默认(包)访问和私有方法。getDeclaredMethod 方法需要两个参数:方法名称和方法参数类型的 Class 对象数组。

参数说明:

  1. name (String 类型):

    • 说明:要获取的方法的名称。
    • 示例:如果方法名为 toString,则传递 "toString"
  2. parameterTypes (Class<?>... 类型,即 Class 对象的变长参数):

    • 说明:方法参数类型的 Class 对象数组。如果方法没有参数,则可以传递 null 或一个空数组。
    • 示例
      • 对于无参方法,可以传递 null 或 new Class<?>[0]
      • 对于有一个 int 类型参数的方法,可以传递 int.class
      • 对于有两个参数的方法,第一个参数为 String 类型,第二个参数为 int 类型,可以传递 new Class<?>[] {String.class, int.class}

返回值:

  • getDeclaredMethod 方法返回一个 Method 对象,该对象表示指定的方法。如果找不到该方法,将抛出 NoSuchMethodException

异常:

  • NoSuchMethodException:如果在该类中找不到指定名称和参数类型的方法。
  • SecurityException:如果请求的操作受到安全管理器的阻止。

示例代码:

java

复制

import java.lang.reflect.Method;public class ReflectionExample {public static void main(String[] args) {try {// 获取ReflectionExample类的Class对象Class<ReflectionExample> cls = ReflectionExample.class;// 获取名为"privateMethod"的私有方法,该方法接受一个String参数Method privateMethod = cls.getDeclaredMethod("privateMethod", String.class);// 输出方法信息System.out.println("方法名称: " + privateMethod.getName());System.out.println("返回类型: " + privateMethod.getReturnType());System.out.println("参数类型: ");for (Class<?> paramType : privateMethod.getParameterTypes()) {System.out.println(" - " + paramType.getName());}} catch (NoSuchMethodException | SecurityException e) {e.printStackTrace();}}// 一个私有方法,用于示例private void privateMethod(String param) {System.out.println("调用私有方法,参数: " + param);}
}

在这个示例中,我们尝试获取 ReflectionExample 类中名为 privateMethod 的私有方法,该方法接受一个 String 类型的参数。我们使用 getDeclaredMethod 方法来获取这个方法的 Method 对象,并打印出方法的相关信息。如果方法不存在或参数类型不匹配,将抛出 NoSuchMethodException

与越过泛型的约束 ——首先要有泛型才行

如果你原方法的参数类型是 String,那么在 getDeclaredMethod 中传入 Object 类型的 Class 对象是不行的。

getDeclaredMethod 方法要求你传入的参数类型数组必须与原方法的参数类型精确匹配。这是因为 Java 的方法重载解析是基于参数类型的,不同的参数类型对应不同的方法签名。

如果你原方法的声明是这样的:

java

复制

public void myMethod(String param) {// 方法实现
}

那么在调用 getDeclaredMethod 时,你应该这样传参:

java

复制

Method method = MyClass.class.getDeclaredMethod("myMethod", String.class);

如果你传入 Object.class,那么它会尝试查找一个参数类型为 Object 的方法,而不是 String。如果不存在这样的方法,就会抛出 NoSuchMethodException

java

复制

// 这将抛出 NoSuchMethodException,因为参数类型不匹配
Method method = MyClass.class.getDeclaredMethod("myMethod", Object.class);

总之,getDeclaredMethod 的参数类型数组必须与原方法的参数类型完全一致。如果你不确定原方法的参数类型,可以使用 getMethod 或 getDeclaredMethods 来获取所有方法,然后遍历并检查每个方法的参数

用户_uBiEPA

可是不是说反射可以越过泛型的约束?

ChatGLM

引用

是的,反射确实可以绕过泛型的约束,但这主要是指在处理泛型类型信息时,反射可以获取到泛型类型的具体类型参数,即使在运行时泛型信息会被擦除。然而,这并不意味着在调用 getDeclaredMethod 或其他反射方法时可以忽略方法签名中的具体参数类型。

当你使用反射来调用方法时,你仍然需要提供正确的方法名称和参数类型。泛型约束的绕过通常发生在以下情况下:

  1. 获取泛型字段的具体类型:即使字段是泛型的,反射可以告诉你它在某个具体实例中的实际类型。
  2. 绕过泛型方法参数的检查:你可以使用反射来调用一个泛型方法,并且传递不符合泛型约束的参数类型,因为泛型信息在运行时会被擦除。

例如,考虑以下泛型方法:

java

复制

public <T> void genericMethod(T param) {// 方法实现
}

在运行时,你可以使用反射来调用这个方法,并且传递任何类型的参数,即使它违反了泛型约束:

java

复制

Method method = MyClass.class.getDeclaredMethod("genericMethod", Object.class);
method.invoke(myObject, "String"); // 这里传递了String,即使泛型约束可能是其他类型

在这个例子中,我们传递了 Object.class 作为参数类型,并且传递了一个字符串作为参数。这之所以可行,是因为泛型信息在运行时被擦除,方法实际上接受的是 Object 类型的参数。

但是,这并不意味着你可以忽略方法签名中的具体参数类型。如果你有一个非泛型方法,其参数类型为 String,你仍然需要使用 String.class 来获取该方法:

java

复制

public void myMethod(String param) {// 方法实现
}// 正确的获取方式
Method method = MyClass.class.getDeclaredMethod("myMethod", String.class);// 错误的获取方式,将抛出 NoSuchMethodException
Method method = MyClass.class.getDeclaredMethod("myMethod", Object.class);

在这个例子中,如果你尝试使用 Object.class 来获取 myMethod,将会抛出 NoSuchMethodException,因为不存在一个接受 Object 类型参数的 myMethod

总结来说,反射可以绕过泛型约束,但在使用 getDeclaredMethod 时,你仍然需要提供与原方法签名匹配的参数类型。

框架

框架”(Framework)在计算机编程领域是一个广泛使用的概念,它指的是一套预设的代码结构和组件,用于简化特定类型应用的开发。框架提供了一种标准化的方式来构建软件,使得开发者可以专注于业务逻辑而不是底层实现。

为什么使用“框架”这个词?

  1. 结构支撑:“框架”一词来源于建筑领域,指的是建筑物的支撑结构。在软件开发中,框架同样提供了应用的支撑结构,确保开发的稳定性和一致性。

  2. 规范和约束:框架提供了一套规范和约束,指导开发者如何组织代码、如何实现功能,从而减少了出错的可能性。

  3. 复用性:框架通常包含了许多可复用的组件和库,开发者可以直接使用这些现成的功能,避免了重复造轮子。

  4. 加速开发:通过提供常见的功能和抽象复杂的底层实现,框架可以显著加快开发速度。

具体框架例子:

  • Spring Boot框架:是一个用于快速构建Java应用的框架。它简化了基于Spring的应用开发,使得开发者可以更轻松地创建、配置和运行应用。

  • PyTorch框架:是一个开源的机器学习库,主要用于构建和训练神经网络。它提供了丰富的API和工具,使得研究人员和开发者可以更高效地进行深度学习实验和开发。

为什么这些工具被称为“框架”?

  • Spring Boot:它提供了一个完整的架构,包括依赖注入、数据访问、安全性等功能,开发者只需要按照框架的规则填充具体的业务逻辑。

  • PyTorch:它为深度学习提供了一套完整的工具和组件,包括自动微分、神经网络层、优化器等,研究者可以在此基础上构建和训练模型。

总的来说,“框架”这个词在软件开发中用来描述那些提供结构、规范、复用性和加速开发能力的工具集。它们就像建筑的骨架一样,为软件的构建提供了坚实的基础

获取不同对象的所有字段

一个对象有4个成员变量,但构造器允许只有三个成员变量创建对象。我用反射作用在三变量的对象上,getdeclaredfields有几个?

ChatGLM

引用

如果一个对象有4个成员变量,但构造器允许只有三个成员变量创建对象,那么使用 getDeclaredFields() 方法反射获取这个类的成员变量时,返回的 Field 数组将包含所有声明的成员变量,即4个。

getDeclaredFields() 方法返回的是类中声明的所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。构造器中初始化的字段数量不会影响 getDeclaredFields() 返回的结果。

示例:

假设有一个类 MyClass,它有四个成员变量 abc 和 d,但构造器只接受三个参数:

java

复制

public class MyClass {private int a;private int b;private int c;private int d; // 这个字段在构造器中未被初始化public MyClass(int a, int b, int c) {this.a = a;this.b = b;this.c = c;// d未被初始化,将保持默认值0}
}

使用反射获取所有声明的字段:

java

复制

MyClass obj = new MyClass(1, 2, 3);
Field[] fields = MyClass.class.getDeclaredFields();System.out.println("Number of declared fields: " + fields.length); // 输出将是4

在这个例子中,getDeclaredFields() 将返回一个包含4个 Field 对象的数组,分别对应 abc 和 d 这四个成员变量。即使 d 在构造器中未被初始化,它仍然是类的一个声明字段,因此会被包含在返回的数组中。

注意事项:

  • getDeclaredFields() 返回的是类中声明的所有字段,不受构造器初始化字段数量影响。
  • 字段的访问修饰符(如私有、公共等)不会影响 getDeclaredFields() 的返回结果。
  • 如果需要获取继承的字段,可以使用 getFields() 方法,但它只返回公共字段,包括继承的公共字段。

总之,无论构造器如何初始化对象,getDeclaredFields() 总是返回类中声明的所有字段的数量。

 

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

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

相关文章

C++手撕单链表及逆序打印

在学习数据结构的过程中&#xff0c;链表是一个非常重要的基础数据结构。今天&#xff0c;我们将通过C手动实现一个单链表&#xff0c;并添加一个逆序打印的功能&#xff0c;帮助大家更好地理解链表的实现和操作。 一、链表简介 链表是一种线性数据结构&#xff0c;其中每个元…

netty中的ChannelPipeline详解

Netty中的ChannelPipeline是事件处理链的核心组件,负责将多个ChannelHandler组织成有序的责任链,实现网络事件(如数据读写、连接状态变化)的动态编排和传播。以下从核心机制、执行逻辑到应用场景进行详细解析: 1. 核心结构与组成 双向链表结构 组成单元:ChannelPipeline…

智能物联网网关策略部署

实训背景 某智慧工厂需部署物联网网关&#xff0c;实现以下工业级安全管控需求&#xff1a; 设备准入控制&#xff1a;仅允许注册MAC地址的传感器接入&#xff08;白名单&#xff1a;AA:BB:CC:DD:EE:FF&#xff09;。协议合规性&#xff1a;禁止非Modbus TCP&#xff08;端口…

前端-vue2核心

官网网址Vue2 安装 — Vue.js 搭建环境 第一种方式&#xff08;刚开是接触Vue&#xff09; 我们看官网&#xff0c;可以直接在script引入vue版本。这里有两个版本&#xff0c;开发版和生产版本。我们两个都下载。 然后创建一个项目&#xff0c;将下载的生产版本和开发版本粘…

【BUG】远程连接阿里云服务器上的redis报错

出现 Redis Client On Error: Error: connect ECONNREFUSED 47.100.XXX.XX:6379 错误&#xff0c;表明 Redis 客户端无法连接到指定的 Redis 服务器&#xff0c;可按以下步骤排查解决&#xff1a; 1. 检查 Redis 服务器是否运行 操作&#xff1a;在 Redis 服务器所在终端执行…

mongodb--用户管理

文章目录 MongoDB 用户管理1. 连接到 MongoDB2. 用户创建2.1 创建管理员用户2.2 创建特定数据库用户2.3 常用内置角色 3. 用户管理操作3.1 查看所有用户3.2 查看特定用户信息3.3 更新用户密码3.4 添加用户角色3.5 移除用户角色3.6 删除用户 4. 权限修改4.1 创建自定义角色4.2 将…

DeepSeek与搜索引擎:AI生成内容如何突破“语义天花板”

一、搜索引擎的“内容饥饿症”与AI的“产能悖论” 2024年&#xff0c;全球每天新增470万篇网络文章&#xff0c;但搜索引擎的索引拒绝率高达68%。这一矛盾的根源在于&#xff1a;算法对“高质量原创”的定义已从“形式独特性”转向“认知增值性”。传统AI生成内容&#xff08;…

YOLO目标检测应用——基于 YOLOv8目标检测和 SAM 零样本分割实现指定目标分割

概述 在当前的计算机视觉领域&#xff0c;目标分割技术正变得越来越重要。市面上有许多分割模型&#xff0c;它们的工作原理大致相似&#xff0c;通常包括收集数据、配置模型以及训练分割模型等步骤。最终目标是实现精确的目标分割。而随着 SAM&#xff08;Segment Anything M…

在Flutter中使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏

在Flutter中&#xff0c;使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏。BottomNavigationBar用于显示底部的导航按钮&#xff0c;而IndexedStack则用于管理页面的切换&#xff0c;确保每个页面的状态得以保留&#xff08;即页面不会因为切换而重新构…

【10】数据结构的矩阵与广义表篇章

目录标题 二维以上矩阵矩阵存储方式行序优先存储列序优先存储 特殊矩阵对称矩阵稀疏矩阵三元组方式存储稀疏矩阵的实现三元组初始化稀疏矩阵的初始化稀疏矩阵的创建展示当前稀疏矩阵稀疏矩阵的转置 三元组稀疏矩阵的调试与总代码十字链表方式存储稀疏矩阵的实现十字链表数据标签…

微服务篇——SpringCloud

服务注册 Spring Cloud5大组件有哪些&#xff1f; 服务注册和发现是什么意思&#xff1f;Spring Cloud如何实现服务注册发现&#xff1f; nacos与eureka的区别 负载均衡 如何实现负载均衡&#xff1f; Ribbon负载均衡的策略有哪些&#xff1f; 如何自定义负载均衡的策略&…

【小沐杂货铺】基于Three.JS绘制三维数字地球Earth(GIS 、WebGL、vue、react,提供全部源代码)

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第二期3【小沐…

Cursor 在前端需求开发工作流中的应用|得物技术

一、引言 很高兴与大家分享现阶段 Cursor 在我的工作中的使用体验。首先是预期管理&#xff0c;本篇文章不会分享 x 个你可能不知道的小技巧&#xff0c;也不会让你拥有无需自行编码的能力&#xff0c;同时不涉及 Cursor 工程化方面内容。仅仅是围绕个人开发流程中的已有问题&…

PyQt学习记录

PyQt学习记录 要在界面上 创建一个控件&#xff0c;就需要在程序代码中 创建 这个 控件对应类 地一个 实例对象。 在Qt系统中&#xff0c;控件&#xff08;widget&#xff09;是 层层嵌套 的&#xff0c;除了最顶层的控件&#xff0c;其他的控件都有父控件。 几个函数 函数mo…

react: styled-components实现原理 标签模版

styled-components是针对react中一个前端广泛使用的css-in-js样式库B站 利用标签模版 利用ES6中的 标签模版文档标签模板其实不是模板&#xff0c;而是函数调用的一种特殊形式。“标签”指的就是函数&#xff0c;紧跟在后面的模板字符串就是它的参数。 let a 5; let b 10;…

网络安全应急响应之文件痕迹排查:从犯罪现场到数字狩猎的进化论

凌晨3点&#xff0c;某金融企业的服务器突然告警&#xff0c;核心数据库出现未知进程访问。安全团队紧急介入时&#xff0c;攻击者已抹去日志痕迹。在这场与黑客的时间赛跑中&#xff0c;文件痕迹排查成为破局关键。本文将带您深入数字取证的"案发现场"&#xff0c;揭…

多模态大语言模型arxiv论文略读(七)

MLLM-DataEngine: An Iterative Refinement Approach for MLLM ➡️ 论文标题&#xff1a;MLLM-DataEngine: An Iterative Refinement Approach for MLLM ➡️ 论文作者&#xff1a;Zhiyuan Zhao, Linke Ouyang, Bin Wang, Siyuan Huang, Pan Zhang, Xiaoyi Dong, Jiaqi Wang,…

idea插件:AICommit,智能生成Git提交信息

AICommit&#xff1a;智能生成Git提交信息的IDEA插件指南 一、AICommit插件介绍 AICommit是一款专为开发者设计的IntelliJ IDEA插件&#xff0c;它利用人工智能技术自动生成清晰、规范的Git提交信息(Commit Message)。该插件能够分析你的代码变更&#xff0c;理解修改的上下文…

js 拷贝-包含处理循环引用问题

在 JavaScript 中&#xff0c;拷贝对象和数组时需要特别注意&#xff0c;因为对象和数组是引用类型&#xff0c;直接赋值只会复制引用&#xff0c;而不是实际的数据。以下是几种常见的拷贝方法及其应用场景&#xff1a; 1. 浅拷贝&#xff08;Shallow Copy&#xff09; 浅拷贝…

oracle将varchar2 转为clob类型存储。 oracle不支持直接使用sql,将 varchar2 到clob的类型转换,需要下面操作

将一个现有表中的 VARCHAR2 列数据迁移到一个 CLOB 列的过程。以下是对每一步操作的说明&#xff1a; 1. 添加一个新的 CLOB 类型列 首先&#xff0c;向表中添加一个新的 CLOB 类型的列。这个列将用来存储原本的 VARCHAR2 数据。 ALTER TABLE your_table ADD (new_column CL…