⛳ Java 反射
目录
- ⛳ Java 反射
- 🎨 一、反射概述
- **🎃 使用反射的前提条件: **
- 🎲 类正常加载过程如下图:
- 反射优缺点:
- 🧸 Java反射机制提供的功能:
- **🥅 反射主要API**
- 🏭 二、反射的使用
- 🎯 2.1、`class`类概述
- 🎒 2.2、得到`Class`的实例
- 📐 2.3、`Java`内置 9 大 `Class`实例
- 📢 2.4、获取类中的构造器
- ✨ 2.5、调用构造器创建对象
- 🚜 2.6、获取类中的成员变量并调用(setAccessible)
- 批量获取的方法:
- 获取单个的方法:
- 设置字段的值:
- 👣 2.7、获取类中的成员方法并调用
- 获取单个的方法:
- 调用方法:
- 🐾 2.8、反射方法的其他使用之通过反射运行配置文件内容
- 🎈 2.9、反射方法的其它使用之越过泛型检查
- 🎁 三、反射面试题
⛳ Java 反射
🎨 一、反射概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助
Reflection API
获取任何类的内部信息,并直接操作任意对象的内部属性及方法。
JAVA
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java
语言的反射机制。
**🎃 使用反射的前提条件: **
必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码),原因是要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
🎲 类正常加载过程如下图:
加载完类之后, 在堆内存的方法区中就产生了一个Class类型的对象( 一个类只有一个Class对象) , 这个对象就包含了完整的类的结构信息。 我们可以通过这个对象看到类的结构。 这个对象就像一面镜子, 透过这个镜子看到类的结构, 所以, 我们形象的称之为: 反射。
反射优缺点:
- 优点
- 可以在运行程序的过程中,操作这些对象。
- 可以降低耦合度,提高程序的可扩展性。
- 缺点
- 反射很强大,但是消耗性能。主要是为了做工具和框架使用的。
🧸 Java反射机制提供的功能:
-
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时获取泛型信息
- 在运行时调用任意一个对象的成员变量和方法
- 在运行时处理注解
- 生成动态代理
🥅 反射主要API
-
- java.lang.Class:代表一个类
- java.lang.reflect.Method:代表类的方法
- java.lang.reflect.Field:代表类的成员变量
- java.lang.reflect.Constructor:代表类的构造器
🏭 二、反射的使用
🎯 2.1、class
类概述
在Object类中定义了以下的方法,此方法将被所有子类继承:public final Class getClass()以上的方法返回值的类型是一个Class类,此类是Java反射的源头,实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。
Class
类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象(包括基本数据类型)。Class
没有公共构造方法。Class
对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass
方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
🎒 2.2、得到Class
的实例
Student stu = new User();
,Class clz = stu.getClass();
:对象.getClass();得到对象的真实类型,因为在Object里,所以每个类都有该方法。Class<Student> clz = Student.class;
: 数据类型.class(就是一份字节码)。Class.forName(String className);
:根据一个类的全限定名来构建Class对象,Class<?> clz = Class.forName("com.gbx.Student");
,这里泛型写<?>原因是此时class不知道类,因为传的是字符串。
代码示例:
package com.gbx;public class Demo {public static void main(String[] args) {//obj.getClass()方式获取Class对象 Student stu1 = new Student();//new 产生一个Student对象,一个Class对象。Class stuClass = stu1.getClass();//获取Class对象//类名.class方式获取Class对象Class stuClass2 = Student.class;//Class.forName(String className)方式获取Class对象try {Class stuClass3 = Class.forName("com.gbx.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名} catch (ClassNotFoundException e) {e.printStackTrace();}}}
注:这三种方法获取的都是同一个class对象,因为表示都是JVM中共同的一份字节码。
📐 2.3、Java
内置 9 大 Class
实例
对于对象来说,可以直接使用obj.getClass()
获取Class
实例,但是基本数据类型,就没有类的权限定名,也没有getClass
方法,那么如何使用Class
类来表示基本数据类型的Class
实例?
byte,short,int,long,char,float,double,boolean ,void
关键字,上述8种类型和void
关键字,都有class
属性。例子如下:
- 表示int的Class对象: Class clz = int.class;
- 表示boolean的Class对象: boolean.class;
- void: Class clz = void.class;
- 表示数组的Class实例:String[] sArr1 = {“A”,“C”},Class clz = String[].class;//所有具有相同元素类型和维数的数组才共享同一份字节码(Class对象);
所有的数据类型都有class属性,表示都是Class对象。
注意:
int的包装类是Integer,那么 Integer.class == int.class ?结果是false,说明是两份字节码.
Integer 和 int 不是同一种数据类型,在八大基本数据类型的包装类中都有一个常量:TYPE,TYPE表示的是该包装类对应的基本数据类型的Class实例。例子如下:
- Integer.TYPE—>int.class
- Integer.TYPE == int.class;//YES
- Integer.TYPE == Integer.class;//ERROR
📢 2.4、获取类中的构造器
-
Class类获取构造器方法:Constructor类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器。
-
批量获取的方法:
-
public Constructor<?>[] getConstructors()
:该方法只能获取当前Class所表示类的public修饰的构造器。 -
public Constructor<?>[] getDeclaredConstructors()
:获取当前Class所表示类的所有的构造器,和访问权限无关。
-
-
获取单个的方法:
public Constructor<T> getConstructor(Class<?>... parameterTypes)
:获取当前Class所表示类中指定的一个public的构造器。public Constructor getDeclaredConstructor(Class<?>... parameterTypes)
:获取当前Class所表示类的所有构造器中指定的一个构造器(可以是私有、受保护、默认、公有等)。
参数parameterTypes表示:构造器参数的Class类型。如:public Student(String name),Constructor c = clz.getConstructor(String.class)
代码示例:
package com.gbx;public class Student {public Student() {System.out.println("---");}public Student(String name) {System.out.println(name);}public Student(String name, String school) {System.out.println(name + " " + school);}}
package com.gbx;public class Constructors {public static void main(String[] args) throws Exception {//1.加载Class对象Class clazz = Class.forName("com.gbx.Student");//2.获取所有公有构造器System.out.println("****所有公有构造器****");Constructor[] conArray = clazz.getConstructors();for(Constructor c : conArray){System.out.println(c);}//3.获取所有构造器System.out.println("****所有的构造器****");conArray = clazz.getDeclaredConstructors();for(Constructor c : conArray){System.out.println(c);}//3.获取单个公有无参构造器System.out.println("****获取单个公有、无参的构造器****");Constructor con = clazz.getConstructor(null);System.out.println(con);//4.获取单个指定公有构造器System.out.println("****获取单个指定的公有构造器****");con = clazz.getConstructor(String.class);System.out.println(con);//5.获取单个指定构造器System.out.println("****获取单个指定的构造器****");con = clz.getDeclaredConstructor(String.class);System.out.println(con);}}
✨ 2.5、调用构造器创建对象
常用方法: public T newInstance(Object... initargs)
:使用此 Constructor
对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例,参数initargs:表示调用构造器的实际参数,返回:返回创建的实例,T表示Class所表示类的类型。
提示:如果一个类中的构造器可以直接访问,同时没有参数,那么可以直接使用Class类中的newInstance方法创建对象,public Object newInstance()
:相当于 new 类名()
代码示例:
public class newInstances {public static void main(String[] args) throws Exception {//1.加载Class对象Class<Student> clz = Student.class;//2.获取构造器Constructor<Student> c = clz.getConstructor(String.class);//3.调用构造器,创建对象Student stu1 = c.newInstance("gbx");//直接访问不带参数的构造器可以直接使用Class的newInstance()方法Student stu2 = clz.newInstance();}}
🚜 2.6、获取类中的成员变量并调用(setAccessible)
-
批量获取的方法:
Field[] getFields()
:获取当前Class所表示类的所有"公有字段"。Field[] getDeclaredFields()
:获取当前Class所表示类的所有字段,包括:私有、受保护、默认、公有。
-
获取单个的方法:
public Field getField(String fieldName)
:获取当前Class所表示类的某个"公有的"字段。public Field getDeclaredField(String fieldName)
:获取当前Class所表示类的某个字段(可以是私有的)。
-
设置字段的值:
public void set(Object obj,Object value)
参数 obj:要设置的字段所在的对象,value:要为字段设置的值
代码示例:
package com.gbx.field;public class Student {public Student(){}//**字段**//public String name;protected int age;char sex;private String phoneNum;
}
package com.gbx.field;
import java.lang.reflect.Field;
public class Fields {public static void main(String[] args) throws Exception {//1.获取Class对象Class stuClass = Class.forName("com.gbx.field.Student");//2.获取字段System.out.println("***获取所有公有的字段***");Field[] fieldArray = stuClass.getFields();for(Field f : fieldArray){System.out.println(f);}System.out.println("***获取所有的字段(包括私有、受保护、默认)***");fieldArray = stuClass.getDeclaredFields();for(Field f : fieldArray){System.out.println(f);}System.out.println("***获取某个"公有的"字段并设置字段值***");Field f = stuClass.getField("name");System.out.println(f);System.out.println("***获取私有字段并设置字段值***");f = stuClass.getDeclaredField("phoneNum");System.out.println(f);//获取构造器,调用构造器获取一个对象Object obj = stuClass.getConstructor().newInstance();//产生Student对象,相当于Student stu = new Student();//为字段设置值f.set(obj, "张三");//为Student对象中的name属性赋值,相当于stu.name = "张三"//检验Student stu = (Student)obj;System.out.println("姓名:" + stu.name); f.setAccessible(true);//Student类中的成员变量phoneNum为private,故必须解除“phoneNum”私有限定f.set(obj, "12345678900");System.out.println("电话:" + stu.phoneNum); }
}
输出:
***获取所有公有的字段***
public java.lang.String com.gbx.field.Student.name
***获取所有的字段(包括私有、受保护、默认的)***
public java.lang.String com.gbx.field.Student.name
protected int com.gbx.field.Student.age
char fanshe.com.gbx.Student.sex
private java.lang.String com.gbx.field.Student.phoneNum
***获取某个“公有的”字段并设置字段值***
public java.lang.String com.gbx.field.Student.name
姓名:张三
***获取私有字段并设置字段值***
private java.lang.String com.gbx.field.Student.phoneNum
电话:12345678900
注:Java反射机制提供的setAccessible()方法,传入true
可以取消,Java的安全检查。
👣 2.7、获取类中的成员方法并调用
-
**批量获取的方法: **
public Method[] getMethods()
:获取当前Class所表示类和继承过来的所有"公有"方法(包含了父类的方法也包含Object类)。public Method[] getDeclaredMethods()
:获取当前Class所表示类的所有成员方法,包括私有的(不包括继承的,和访问权限无关)。
-
获取单个的方法:
-
public Method getMethod(String name,Class<?>... parameterTypes)
:获取当前Class所表示类的某个"公有"方法(包括继承的)。 -
public Method getDeclaredMethod(String methodName,Class<?>... parameterTypes)
:获取当前Class所表示类的某个成员方法(不包括继承的)。参数
methodName
:方法名,Class ... parameterTypes
:形参的Class类型对象
-
-
调用方法:
public Object invoke(Object obj,Object ... args)
参数 obj:要调用方法的对象,args:调用方法时所传递的实参
代码演示:
package com.gbx.method;public class Student {//****成员方法****//public void show1(String s){System.out.println("调用公有的String参数的show1(): s = " + s);}protected void show2(){System.out.println("调用受保护的无参的show2()");}void show3(){System.out.println("调用默认的无参的show3()");}private String show4(int age){System.out.println("调用私有的且有返回值的int参数的show4(): age = " + age);return age;}
}
package com.gbx.method;import java.lang.reflect.Method;public class MethodClass {public static void main(String[] args) throws Exception {//1.获取Class对象Class stuClass = Class.forName("com.gbx.method.Student");//2.获取所有公有方法System.out.println("****获取所有”公有“方法****");Method[] methodArray = stuClass.getMethods();for(Method m : methodArray){System.out.println(m);}System.out.println("****获取所有本类方法,包括私有****");methodArray = stuClass.getDeclaredMethods();for(Method m : methodArray){System.out.println(m);}System.out.println("****获取公有的show1()方法****");Method m = stuClass.getMethod("show1", String.class);System.out.println(m);//实例化一个Student对象Object obj = stuClass.getConstructor().newInstance();//调用方法,相当于stu.show1("张三")m.invoke(obj, "张三");System.out.println("****获取私有的show4()方法****");m = stuClass.getDeclaredMethod("show4", int.class);System.out.println(m);m.setAccessible(true);//解除私有限定Object result = m.invoke(obj, 20);System.out.println("返回值:" + result);}
}
输入:
****获取所有”公有“方法****
public void com.gbx.method.Student.show1(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
****获取所有本类方法,包括私有****
public void com.gbx.method.Student.show1(java.lang.String)
private java.lang.String com.gbx.method.Student.show4(int)
protected void com.gbx.method.Student.show2()
void com.gbx.method.Student.show3()
****获取公有的show1()方法****
public void com.gbx.method.Student.show1(java.lang.String)
调用公有的String参数的show1(): s = 张三
****获取私有的show4()方法****
private java.lang.String com.gbx.method.Student.show4(int)
调用私有的且有返回值的int参数的show4(): age = 20
返回值:20
🐾 2.8、反射方法的其他使用之通过反射运行配置文件内容
Student类:
public class Student {public void show(){System.out.println("It is show()");}
}
配置文件以txt文件为例子(p.txt):
className = com.gbx.Student
methodName = show
代码示例:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;public class Demo {public static void main(String[] args) throws Exception {//通过反射获取Class对象Class stuClass = Class.forName(getValue("className"));//"com.gbx.Student"//2获取show()方法Method m = stuClass.getMethod(getValue("methodName"));//show//3.调用show()方法m.invoke(stuClass.getConstructor().newInstance()); }//此方法接收一个key,在配置文件中获取相应的valuepublic static String getValue(String key) throws IOException{Properties p = new Properties();//获取配置文件的对象FileReader fr = new FileReader("p.txt");//获取字符输入流p.load(fr);//将流加载到配置文件对象中in.close();return p.getProperty(key);//返回根据key获取的value值}
}
优点:当我们升级这个系统时,不要Student类,而需要新写其他类时,这时只需要更改p.txt里的文件内容就可以了,代码不用改动。
🎈 2.9、反射方法的其它使用之越过泛型检查
泛型用在编译期,编译过后泛型擦除(消失),所以是可以通过反射越过泛型检查的。
例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值?
代码示例:
import java.lang.reflect.Method;
import java.util.ArrayList;public class Demo {public static void main(String[] args) throws Exception{ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");//list.add(100);//获取ArrayList的Class对象,反向的调用add()方法,添加数据Class listClass = list.getClass(); //得到 list对象的字节码对象//获取add()方法Method m = listClass.getMethod("add", Object.class);//调用add()方法m.invoke(list, 100);//遍历集合for(Object obj : list){System.out.println(obj);}}
}
输出:
aaa
bbb
100
这样说明可以通过反射越过泛型检查,向String泛型的集合中添加一个Integer类型的值。
🎁 三、反射面试题
题目:如何在不改变String内存地址的情况下,改变String的内容
正常创建:
@Test
public void test3() {String s = new String("abc"); //堆里面产生sString s1 = s; //s1s = "123";String s2 = s;System.out.println(s1.hashCode() + " " + s2.hashCode() );System.out.println(s1 == s2);
}
/**
* 结果:
* 96354 48690
* false
*/
图示:
通过反射操作String中的value属性:
@Test
public void test4() throws Exception {String s = new String("123"); //堆里面产生sString s1 = s; //s1Field vf = String.class.getDeclaredField("value");vf.setAccessible(true);char[] chars = {97, 98, 99};vf.set(s, chars);String s2 = s;System.out.println(s1.hashCode() + " " + s2.hashCode() );System.out.println(s1 == s2);/*** 结果:* 96354 96354* true**/
}
图示:
相关文章:

⛳ Java 反射
目录 ⛳ Java 反射🎨 一、反射概述**🎃 使用反射的前提条件: **🎲 类正常加载过程如下图:反射优缺点:🧸 Java反射机制提供的功能: **🥅 反射主要API** 🏭 二、反射的使用Ἲ…...
Android 13 像Settings一样开启关闭深色模式
一.背景 由于客户定制的Settings需要开启关闭深色模式,所以需要自己调用开启关闭深色模式 二.前提条件 首先应用肯定要是系统应用,并且导入framework.jar包,具体可以参考: Android 应用自动开启辅助(无障碍)功能并使用辅助(无障碍)功能_android 自动开启无障碍服务_龚礼鹏…...

微服务实战项目-学成在线-项目优化(redis缓存优化)
微服务实战项目-学成在线-项目优化(redis缓存优化) 1 优化需求 视频播放页面用户未登录也可以访问,当用户观看试学课程时需要请求服务端查询数据,接口如下: 1、根据课程id查询课程信息。 2、根据文件id查询视频信息。 这些接口在用户未认…...

IDEA 找不到项目 ‘org.springframework.boot:spring-boot-starter-parent:3.1.2‘
找不到项目 ‘org.springframework.boot:spring-boot-starter-parent:2.6.7’ 这个问题主要是因为ide的缓存导致的,我们直接清理缓存并重启ide 重启之后ide会对pom文件进行编排索引完成之后问题就没有了...

thinkphp开发的在线学习培训考试模拟考试做题练习系统带商城功能证书管理课程系统
thinkphp开发的在线学习培训考试模拟考试做题练习系统带商城功能证书管理课程系统 1、做题界面 2、前端UI的展示 3、带商城购物功能...
Android 应用冷启动优化
冷启动相关概念 应用启动概念 冷启动:首次打开app或者app彻底销毁后再次打开app(开关机后),这也是我们进行启动速度优化的主要方向。热启动:应用运行中按home键再打开应用。温启动:介于两者之间ÿ…...

538页21万字数字政府智慧政务大数据云平台项目建设方案WORD
导读:原文《538页21万字数字政府智慧政务大数据云平台项目建设方案WORD》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 根据业务的不同属性,…...

进程间通信——信号
信号的概念 信号是 Linux进程间通信的最古老的方式之一,是事件发生时对进程的通知机制,有时也称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在运行的异…...
PAT 1039 Course List for Student
个人学习记录,代码难免不尽人意。 Zhejiang University has 40000 students and provides 2500 courses. Now given the student name lists of all the courses, you are supposed to output the registered course list for each student who comes for a query. …...
【Sklearn】基于决策树算法的数据分类预测(Excel可直接替换数据)
【Sklearn】基于决策树算法的数据分类预测(Excel可直接替换数据) 1.模型原理1.1 模型原理1.2 数学模型2.模型参数3.文件结构4.Excel数据5.下载地址6.完整代码7.运行结果1.模型原理 决策树是一种基于树状结构的分类和回归模型,它通过一系列的决策规则来将数据划分为不同的类…...

并发编程4:Java 中的并发基础构建模块
目录 1、同步容器类 1.1 - 同步容器类的问题 1.2 - 迭代和容器加锁 2、并发容器类 2.1 - ConcurrentHashMap 类 2.2 - CopyOnWriteArrayList 类 3、阻塞队列和生产者-消费者模式 3.1 - 串行线程封闭 4、阻塞方法与中断方法 5、同步工具类 5.1 - 闭锁 -> CountDow…...

Vue-10.集成(.editorconfig、.eslintrc.js、.prettierrc)
介绍 同时使用 .editorconfig、.prettierrc 和 .eslintrc.js 是很常见的做法,因为它们可以在不同层面上帮助确保代码的格式一致性和质量。这种组合可以在开发过程中提供全面的代码维护和质量保证。然而,这也可能增加一些复杂性,需要谨慎配置…...
PHP-FPM进程排查
1、查看php-fpm的进程个数 ps -ef |grep "php-fpm"|grep "pool"|wc -l2、查看每个php-fpm占用的内存大小 ps -ylC php-fpm --sort:rss3.查看PHP-FPM在你的机器上的平均内存占用 ps --no-headers -o "rss,cmd" -C php-fpm | awk { sum$1 } END…...

PHP-MD5注入
0x00 前言 有些零散的知识未曾关注过,偶然捡起反而更加欢喜。 0x01 md5 注入绕过 md5函数有两个参数,第一个参数是要进行md5的值,第二个值默认为false,如果为true则返回16位原始二进制格式的字符串。意思就是会将md5后的结果当…...
对redis、redisson、springcache总结
<一> redis-缓存中间件 什么是redis redis是c语言开发的,一个高性能key-value键值对内存数据库,可以用来做数据库、缓存、消息中间件的一种非关系型数据库。 redis数据存储在哪里 内存和磁盘中,但是redis的读写都在内存中,…...

Java基础知识实际应用(学生信息管理系统、猜拳小游戏、打印日历)
一、Java学生信息管理系统 这个系统包含了添加、修改、删除、查询和显示所有学生信息等功能。您可以在此基础上进行修改和完善,以适应您的需求。 import java.util.Scanner;public class StudentManagementSystem {private static Scanner scanner new Scanner(S…...

Git:在本地电脑上如何使用git?
git 版本: 2.40.1.windows.1 文章目录 一. 使用git之前你必须要理解的几个概念1.1 理解工作区、版本库、暂存区的概念1.2 提交Git版本库的步骤【分两步执行】 二. Git本地库实战2.1 初始化版本库2.2 新建 & 提交 & 状态2.3 查看日志2.4 回退 & 穿梭 &am…...
卷和分区的关系
1、分区 存储空间管理和仓库管理类似,只不过仓库管理的是货物,存储空间管理的是文件。当仓库规模小时,可以不划分货物的存放区域,但当仓库规模很大,就必须根据货物的类型和存储需要,把仓库分为多个区域。例…...

Linux下在qtcreator中创建qt程序
目录 1、新建项目 2、单工程项目创建 3、多工程项目创建 4、添加子工程(基于多工程目录结构) 5、 .pro文件 1、新建项目 切换到“编辑”界面,点击菜单栏中的“文件”-“新建文件或项目” 2、单工程项目创建 只有一个工程的项目&#…...

快递再多也不怕!你的顺丰快递用上5G“神器”
互联网时代,剁手党疯狂“买买买”之后,快递件量再创新高。《2023年6月中国快递发展指数报告》显示,2023二季度单月快递业务量稳定在百亿件以上。其中,由于“618”电商促销活动与父亲节叠加,6月16日至20日单日揽收量均超…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...