Java 入门指南:反射机制

news2024/9/22 15:34:13

RTTI

RTTI(Run-Time Type Identification)是一种在运行时确定对象类型的机制。它是一种编程语言特性,主要用于在运行时动态识别和处理对象的实际类型

通过 RTTI,可以在运行时根据对象的实际类型执行相应的操作。这在处理多态对象和基于继承的代码逻辑时非常有用。

Java中的RTTI

在Java中,RTTI 主要通过以下两种方式实现:

  1. instanceof 运算符:假定我们在编译时已经知道了所有的类型,可以使用 instanceof 运算符来检查对象是否是特定类的实例或其子类的实例。

    它返回一个布尔值来指示对象是否可以转换为指定的类型。例如:

if (obj instanceof MyClass) {
	// 对象是MyClass类型或其子类的实例
}
  1. getClass() 方法:利用反射机制,在运行时发现和使用类的信息

    每个Java对象都有 getClass() 方法,它返回一个表示对象所属类的 Class 对象。可以使用 getClass() 方法来获取对象的实际运行时类型。例如:

Class clazz = obj.getClass(); // 获取对象的实际类型

反射机制

反射机制是指在运行时动态地获取类的信息并操作类和对象的方法和属性。它是一种 Java 语言的特性,可以让程序在运行时获取类的信息,包括类型、属性、方法等,并且可以在运行时动态地创建对象、调用对象的方法、修改属性等。

Java反射机制的实现是通过 Java.lang.Class 类来实现的,Class类提供了许多方法来获取类的信息。通过 Class 类可以获取类的名称、继承关系、方法、属性等,还可以创建对象、调用方法等。

优点

Java 反射机制的优点是可以动态地获取和使用类的信息,这使得 Java 程序的灵活性更高,开发人员可以根据需要在运行时动态地调整程序,让程序更加灵活、可扩展。

缺点

  • 破坏封装:由于反射允许访问私有字段和私有方法,所以可能会破坏封装而导致安全问题。

  • 性能开销:由于反射涉及到动态解析,因此无法执行 Java 虚拟机优化,再加上反射的写法的确要复杂得多,所以性能要比“正射(直接使用类)”差很多,在一些性能敏感的程序中应该避免使用反射。

Java 反射机制的性能相对较低,使用不当还可能会导致程序运行失败或者出现安全漏洞,需要根据具体情况仔细使用。

应用场景

  • 开发通用框架:例如 Spring,为了保持通用性,通过配置文件来加载不同的对象,调用不同的方法。

  • 动态代理:在 面向切面编程(AOP)中,需要拦截特定的方法,就会选择动态代理的方式,而动态代理的底层技术就是反射。

  • 注解:注解本身只是起到一个标记符的作用,它需要利用反射机制,根据标记符去执行特定的行为。

  • RPC框架:RPC(远程过程调用)框架通过反射机制动态地生成类和方法调用,实现远程服务的调用。

  • 单元测试:在单元测试中,可以使用反射机制来调用私有方法或访问私有成员变量,从而进行更全面的测试。

反射机制的使用

Class 类

在Java中,Class类是反射机制的核心类之一,与class关键字不同。每个类都有一个与之关联的Class对象,该对象包含了有关类的元数据信息(如类的名称、字段、方法、构造函数等)。

Class类,位于 JDK 的 java.lang 包中。Class类的实例表示 java 应用运行时的 类 class ans enum 或 接口 interface and annotation

java.lang.class 是所有反射API的入口

  • 手动编写的类被编译后(JVM 加载类时)会产生一个 Class对象,其表示的是创建的类的元数据,这个 Class对象保存在 同名.class 的文件中(字节码文件)

  • 每个通过关键字 class 标识的类,在 JVM 中有且只有一个与之对应的Class对象来描述其类型信息,无论创建多少个实例对象,其依据的都是用一个 Class对象。

  • Class类 只存私有构造函数,因此对应Class对象只能由JVM创建和加载

  • Class类 的对象作用是运行时提供或获得某个对象的类型信息,这点对于反射技术很重要

源代码

source code.png]]

数组同样也被映射为 class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

基本类型 booleanbytecharshortintlongfloatdouble 和关键字 void 同样表现为 class 对象。

每个 java类 运行时都在 JVM 里表现为一个 class对象,可通过类名.class类型.getClass()Class.forName("ClassName") 等方法获取class对象。

Class类 没有公共构造函数。相反,当一个类是类文件的字节中派生类时,Java虚拟机会通过调用以下方法之一,自动构造Class对象:

ClassLoader::defineClass

java.lang.invoke.MethodHandles.Lookup::defineClass

java.lang.invoke.MethodHandles.Lookup::defineHiddenClass

ClassLoader

在Java中,每个类都有一个与之关联的 ClassLoader 对象,用于在运行时动态加载类和资源。

ClassLoader 是 Java 的一个能够动态加载类和资源的机制,它是 Java 虚拟机的重要组成部分。ClassLoader 根据特定的策略从文件系统、Jar包、网络等地方加载字节码文件到内存中,并根据需要链接、解析和初始化类。

每个 ClassLoader 对象都有一个 父ClassLoader,它们被组织成ClassLoader树形结构,Java虚拟机通过使用 ClassLoader树 来确保每个类只被加载和链接一次,避免对同一个类重复创建多个实例。

对于Java中的类Class,它也有一个 ClassLoader 对象,用于加载该类对应的字节码文件

  • getClassLoader():获取加载该类的ClassLoader对象。

使用Java类时,如果没有显示地指定一个 ClassLoader,那么该类将由系统默认的 ClassLoader 进行加载。

如果需要自定义 ClassLoader 来实现特定的功能,例如从自定义的资源中加载类或者版本控制,可以通过继承 URLClassLoader 或者ClassLoader类来实现自己的 ClassLoader。

binaryname

在Java中,每个类都有一个二进制名称(binary name),用于唯一标识一个类。二进制名称是类的全限定名(fully qualified name),其中包括类所在的包路径和类名。

二进制名称的格式遵循以下约定:

  1. 使用"."来分隔包路径和类名。例如,类 com.example.MyClass 的二进制名称为 com.example.MyClass

  2. 对于内部类,使用 $ 来分隔内部类和外部类。例如,内部类 MyClass 在外部类 com.example.OuterClass 中,其二进制名称为com.example.OuterClass$MyClass

二进制名称在Java中广泛应用于反射、类加载等场景中,可以通过Class对象的 getName() 方法获取一个类的二进制名称。

需要注意的是,二进制名称与Java源代码中的类名是相对应的,但在某些情况下可能会有差异。

如果类是通过编译时注解处理器生成的,二进制名称可能会包含特殊字符或编码,这与源代码中的名称不完全一致。
对于数组类型,我们可以通过在类名后添加 [] 来表示多维数组,如int[]的二进制名称为[I]

在使用Java类时,我们通常要使用完整的二进制名称来标识一个类,特别是在动态加载和热部署等场景中,以避免类名冲突和不一致问题。

Class 类方法

Class类提供了许多用于操作和查询类信息的方法,如下所示:

  1. 实例化Class对象

    • Class.forName(String className):通过类的全限定名获取Class对象。

    • obj.getClass():通过对象获取其所属的Class对象。

  2. 获取类的相关信息

    • getName():获取类的名称。

    • getSimpleName():只获取类名

    • getCanonicalName():主要用于输出(toString)或log打印,大多数情况下和 getName() 一样,输出内部类、数组等其他类型表现形式不同。
      不能用getCanonicalName去加载类对象,必须用getName

    • getPackage():获取类所在的包。

    • getModifiers():获取修饰符的整数表示。

    • getField(String name):获取指定名称的公共字段。

    • getFields():获得某个类的所有的公共(public)的字段,包括继承自父类的所有公共字段。

    • getDeclaredFields():获取所有字段的数组,包括私有字段

    • getMethod(String name, Class<?>... parameterTypes):获取指定名称和参数类型的公共方法。

    • getDeclaredMethods():获取所有方法的数组,包括私有方法。

    • getConstructor(Class<?>... parameterTypes):获取指定参数类型的公共构造函数。

    • getDeclaredConstructors():获取所有构造函数的数组,包括私有构造函数。

    • getInterfaces():返回Class对象数组,表示Class对象所引用的类所实现的所有接口。

    • getSuperClass():返回目标类的父类对应的Class对象

  3. 创建对象和实例化

    • newInstance():通过默认构造函数创建对象。

    • newInstance(Object... initargs):通过指定构造函数创建对象。

  4. 类型判断和转换

    • isAssignableFrom(Class cls):判断Class对象是否可以赋值给指定的Class。

    • isInstance(Object obj):判断对象是否是Class的实例。

    • cast(Object obj):将对象强制转换为Class的类型。

获取 class 对象

获取 class对象 的方式的主要有三种

  • 根据类名:类名.class

  • 根据对象:对象.getClass()

  • 根据全限定类名:Class.forName("全限定类名")

类加载机制

![[Pasted image 20231211000237.png]]

![[Pasted image 20231211000241.png]]

Constructor类

Constructor 类是一个反射类,它提供了对构造器的封装和操作。通过Constructor 类,可以动态地获取、创建和调用类的构造器

使用 Constructor 类,可以在运行时通过反射机制获取类的构造器,并动态地创建和使用类的实例。这在某些特定的场景下非常有用,例如动态加载类实例化对象调用私有构造器等。

常用方法

Constructor类的常用方法包括:

![[Pasted image 20231211213156.png]]

  • getModifiers():获取构造器的修饰符。

  • isAccessible()setAccessible(boolean flag):控制构造器的可访问性。

若未显式地声明类的 public 构造函数时,应使用 getDeclaredConstructor() 获取类的构造器

与Class类相关的方法

![[Pasted image 20231211175414.png]]

Method类

Method 类是一个反射类,它提供了对类或接口的方法的封装和操作。通过 Method类,可以动态地获取和调用类的方法。反射的方法可能是类方法或实例方法(包括抽象方法)。

常用方法

![[Pasted image 20231211224021.png]]

与Class类相关的方法

![[Pasted image 20231211215818.png]]

Field类

Field 类是一个反射类,它提供了对类或接口的成员字段(属性)的封装和操作。通过 Field 类,可以动态地获取和修改类的字段的值。反射的字段可能是一个类(静态)字段或实例字段。

常用方法

![[Pasted image 20231211215023.png]]

与Class类相关的方法

可以通过 Class 类的提供的方法来获取代表字段信息的 Field 对象

![[Pasted image 20231211213614.png]]

获取 指定字段 名称的Field类时,注意字段修饰符必须为 public 且存在该字段,否则会抛出 NoSuchFieldException

在设置值的方法上,Field类还提供了专门针对基本数据类型的方法,如setInt()/getInt()setBoolean()/getBooleansetChar()/getChar() 等等方法

Type 接口

java.lang.reflect.Type 接口,用于表示 Java 类型的通用接口。Type 接口是整个 Java 反射机制的核心,它提供了表示各种类型(如类、接口、数组、参数化类型、类型变量等)的方法和属性。

![[Pasted image 20231211224443.png]]

Type 接口是一个顶级接口,定义了一些通用的方法,同时还有一些子接口和实现类来具体表示不同的类型。

除了 Type 接口之外,以下是一些常见的 Type 接口的子接口和实现类:

  • Class:表示类或接口类型。

  • ParameterizedType:表示参数化类型,例如 List<String>

  • TypeVariable:表示类型变量,例如泛型类型中的 <T>

  • WildcardType:表示通配符类型,例如 ? extends Number

  • GenericArrayType:表示泛型数组类型,例如 T[]

通过使用 Type 接口及其子接口和实现类,可以在反射期间获取和操作不同类型的信息。这对于处理泛型、读取类型参数、获取类型的父类或实现的接口等操作非常有用。

Modifier

java.lang.reflect.Modifier 是 Java 反射库中的一个实用类,它提供了一组用于操作和解析修饰符的静态方法。修饰符是用于描述类、方法、字段等元素的特征和访问级别的标志。

获取修饰符

getModifiers() 用于获取一个类、字段、方法或构造函数的修饰符。它返回一个表示修饰符的整数值。

修饰符常量含义
Modifier.PUBLICpublic 修饰符
Modifier.PRIVATEprivate 修饰符
Modifier.PROTECTEDprotected 修饰符
Modifier.STATICstatic 修饰符
Modifier.FINALfinal 修饰符
Modifier.ABSTRACTabstract 修饰符
Modifier.SYNCHRONIZEDsynchronized 修饰符
Modifier.VOLATILEvolatile 修饰符
Modifier.TRANSIENTtransient 修饰符
Modifier.NATIVEnative 修饰符
Modifier.INTERFACE接口修饰符
Modifier.ANNOTATION注解修饰符
Modifier.ENUM枚举修饰符
常用方法

Modifier 类提供了一些常用的静态方法,可以用于检查和解析修饰符。下面是一些常用的方法:

方法名描述
isPublic(int mod)检查修饰符是否为 public。
isPrivate(int mod)检查修饰符是否为 private。
isProtected(int mod)检查修饰符是否为 protected。
isStatic(int mod)检查修饰符是否为 static。
isFinal(int mod)检查修饰符是否为 final。
isAbstract(int mod)检查修饰符是否为 abstract。
isSynchronized(int mod)检查修饰符是否为 synchronized。
isVolatile(int mod)检查修饰符是否为 volatile。
isTransient(int mod)检查修饰符是否为 transient。
isNative(int mod)检查修饰符是否为 native。
isInterface(int mod)检查修饰符是否为接口。
isAnnotation(int mod)检查修饰符是否为注解类型。
isEnum(int mod)检查修饰符是否为枚举类型。

这些方法接受一个表示修饰符的整数值,可以使用位操作符 &| 来组合和操作修饰符的整数值。

反射机制的执行流程

![[Pasted image 20231212003311.png]]

  1. 反射类及反射方法的获取,都是通过从列表中搜寻查找匹配的方法,所以查找性能会随类的大小方法多少而变化;

  2. 每个类都会有一个与之对应的 Class 实例,从而每个类都可以获取 method 反射方法,并作用到其他实例身上;

  3. 反射本身不是线程安全的,并且在使用反射进行对象操作时需要确保线程安全。在多线程环境下,如果多个线程同时对同一个类或对象进行反射操作,可能会导致并发竞争和数据不一致的问题。

  4. 反射使用软引用 relectionData 缓存class信息,避免每次重新从 JVM 获取带来的开销;

  5. 反射调用多次生成新代理 Accessor, 而通过字节码生存的则考虑了卸载功能,所以会使用独立的类加载器;

  6. 当找到需要的方法,都会copy一份出来,而不是使用原来的实例,从而保证数据隔离;

  7. 调度反射方法,最终是由 JVM 执行 invoke0()执行.

forName()

java.lang.Class.forName() 反射获取类信息,并没有将实现留给 java,而是交给了 JVM 去加载。

主要是先获取 ClassLoader, 然后调用 native 方法,获取信息,加载类则是回调 java.lang.ClassLoader.

最后,JVM 又会回调 ClassLoader 进类加载。

newInstance()

newInstance() 主要做了三件事:

  1. 权限检测,如果不通过直接抛出异常;

  2. 查找无参构造器,并将其缓存起来;

  3. 调用具体方法的无参构造方法,生成实例并返回

getConstructor()

getConstructor0() 为获取匹配的构造方器;分三步:

  1. 先获取所有的 constructors, 然后通过进行参数类型比较;

  2. 找到匹配后,通过 ReflectionFactory copy一份constructor返回;

  3. 否则抛出 NoSuchMethodException;

getMethods()

一旦你有了Class 对象,就可以使用反射API来查询类的信息,如字段、方法、构造器等。getMethods()getMethod(String name, Class<?>... parameterTypes) 就是用来查询方法信息的。

invoke()

![[Pasted image 20231212002219.png]]

MethodAccessor

MethodAccessor 是 Java 反射 API 中的一个接口,用于提供对方法的快速调用,在一定程度上可以提升方法调用的性能。

在 Java 中,通过反射调用方法时,通常使用 Method 对象的 invoke() 方法来执行方法调用。每次调用 invoke() 方法都需要进行一系列的检查和动态分派,这会带来一定的性能开销。

为了优化方法调用的性能,Java 提供了 MethodAccessor 接口。它是 sun.reflect 包下的一个内部接口,用于快速执行方法调用。 MethodAccessor 接口只定义了一个方法 invoke(),它可以直接执行方法的调用,无需每次都进行反射操作。

sun.reflect 包下的实现类 MethodAccessorImpl 实现了 MethodAccessor 接口,并通过一些优化手段提升了方法调用的性能。但是需要注意的是,sun.reflect 包是非标准的、非公共的 API,它的使用不被官方推荐,也不建议直接使用。

MethodAccessor 和 invoke()

invoke() 方法实际上是委派给 MethodAccessor 接口来完成的。

MethodAccessor 接口有三个实现类,其中的 MethodAccessorImpl 是一个抽象类,另外两个具体的实现类继承了这个抽象类。

  • NativeMethodAccessorImpl:通过本地方法来实现反射调用;

  • DelegatingMethodAccessorImpl:通过委派模式来实现反射调用;

通过 debug 的方式进入 invoke() 方法后,可以看到第一次反射调用会生成一个委派实现 DelegatingMethodAccessorImpl,它在生成的时候会传递一个本地实现 NativeMethodAccessorImpl

即,invoke() 方法在执行的时候,会先调用 DelegatingMethodAccessorImpl,然后调用 NativeMethodAccessorImpl,最后再调用实际的方法。

委派模式

采用委派实现而不直接调用本地实现,是为了能够在本地实现和动态实现之间切换。动态实现是另外一种反射调用机制,它通过生成字节码的形式来实现。

如果反射调用的次数比较多,动态实现的效率就会更高,因为本地实现需要经过 Java 到 C/C++ 再到 Java 之间的切换过程,而动态实现不需要;但如果反射调用的次数比较少,反而本地实现更快一些。

调用次数的临界点默认值为 15,可以通过
-Dsun.reflect.inflationThreshold 参数类调整

若次数小于15次,由 JVM 调用;大于15次,由 java 代码生成

第 16 次执行的时候,会进入到 if 条件分支中,改变 DelegatingMethodAccessorImpl 的委派模式 delegate 为 (MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod(),而之前的委派模式 delegate 为 NativeMethodAccessorImpl

![[Pasted image 20231212003008.png]]

总结

Java反射机制是Java语言的一个重要特性,它提供了在运行时动态检查和操作类的能力。虽然反射机制在灵活性和降低耦合度方面具有优势,但也存在性能、安全和可读性问题。因此,在使用反射机制时需要权衡其优缺点,并谨慎使用。

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

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

相关文章

sdn nce insight

SDN&#xff08;Software-Defined Networking&#xff09; 和 NFV&#xff08;Network Functions Virtualization&#xff09; 是现代网络架构中的两项关键技术&#xff0c;它们共同推动了网络的虚拟化、自动化和灵活性。尽管它们各自有不同的焦点和应用领域&#xff0c;但通常…

HarmonyOS应用四之页面加载构建以及数据请求

目录&#xff1a; 1、加载网络页面/本地页面/html页面2、页面布局3、HTTP/HTTPS的数据请求4、上传图片并保存数据 1、加载网络页面/本地页面/html页面 // xxx.ets import { webview } from kit.ArkWeb; import { BusinessError } from kit.BasicServicesKit;Entry Component s…

Java面试八股之消息队列中推模式和拉模式分别有哪些使用场景

消息队列中推模式和拉模式分别有哪些使用场景 消息队列的推模式&#xff08;Push&#xff09;和拉模式&#xff08;Pull&#xff09;各有不同的使用场景和优缺点。下面我会详细介绍这两种模式及其适用场景&#xff1a; 推模式&#xff08;Push&#xff09; 特点&#xff1a;…

进哥在线shinyapps工具(自备)

Jingle’s shinyapps toolkit – 王进的个人网站 (jingege.wang) 一些常用生物信息学分析可视化apps&#xff0c;以及一些分子生物学分析工具&#xff08;尴尬&#xff0c;一直忘记附上链接&#xff09; Jingles toolkit 可以进行多种分析&#xff1a; 1. General plots示例…

putty中修改默认窗口大小和字体、字号

在WinSCP中调用putty&#xff0c;发现默认窗口太小&#xff0c;字号也很小&#xff0c;非常不友好。现在显示器都是1080p起步&#xff0c;所以很有必要修改之。 以中文版v0.70为例&#xff0c;方法&#xff1a; 1. 点击左上角图标 &#xff0c;选择下拉菜单中的“修改设置”&…

Qt-信号和槽(8)

目录 信号的概念 Qt中的信号三要素 connect函数 connect的原型 connect的使用 信号函数和槽函数 参数匹配 close关闭槽函数 运行结果 第一个问题&#xff1a;怎么知道 手册使用 第二个问题&#xff0c;为什么可以直接传递函数指针 自定义槽函数 第一种自定义槽函…

Flask详细教程

1、Flask是什么&#xff1f; Flask是一个非常小的PythonWeb框架&#xff0c;被称为微型框架&#xff08;类似Java的SpringBoot&#xff09;&#xff1b;只提供了一个稳健的核心&#xff0c;其他功能全部是通过扩展实现的&#xff1b;意思就是我们可以根据项目的需要量身定制&a…

前端css动画transform多个属性值写法

X轴平移400px transform: translateX(400px); X轴平移400px并缩小0.5倍 transform: translateX(400px) scale(0.5); X轴平移400px并旋转45度 transform: translateX(400px) rotate(45d…

农产品智慧物流系统pf

TOC springboot537农产品智慧物流系统pf 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各行…

全新分支版本!微软推出Windows 11 Canary Build 27686版

已经很久没有看到 Windows 11 全新的分支版本了&#xff0c;今天微软发布 Windows 11 Canary 新版本&#xff0c;此次版本号已经转移到 Build 27xxx&#xff0c;首发版本为 Build 27686 版。 此次更新带来了多项改进&#xff0c;包括 Windows Sandbox 沙盒功能切换到 Microsof…

『 Linux 』利用UDP套接字实现简单群聊

文章目录 服务端通过传入命令处理实现远程命令执行使用Windows编辑UDP客户端实现Windows远程控制Linux接收套接字的其他信息UDP套接字简单群聊服务端UDP套接字简单群聊客户端运行测试及分离输入输出 参考代码 服务端通过传入命令处理实现远程命令执行 『 Linux 』利用UDP套接字…

led台灯对眼睛好不好?台灯太亮会影响视力吗?解锁护眼台灯小知识

中国的近视情况十分严峻&#xff0c;尤其在青少年群体中表现得更为突出。据统计&#xff0c;中国青少年的近视率高居世界第一&#xff0c;这主要与长时间的近距离用眼、过度使用电子产品以及户外活动时间减少等因素有关。优质的护眼台灯不仅能减少近视的发生率&#xff0c;还能…

创建一个简单的Vue3.0应用程序

1、Vue.createApp() 方法的介绍 每一个 Vue.js 的应用都需要创建一个应用程序的实例对象并挂载到指定 DOM 上。在 Vue3.0 中&#xff0c;创建一个应用程序实例的语法格式如下&#xff1a; Vue.createApp(App) createApp() 是一个全局 API&#xff0c;它接收一个根组件选项对…

基于SpringBoot+Vue疫情物资捐赠和分配系统--论文pf

TOC springboot518基于SpringBootVue疫情物资捐赠和分配系统--论文pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往…

开源一款H5自适应留言表白墙php源码下载

开源一款H5自适应留言表白墙php源码下载&#xff0c;优点就是安装简单&#xff0c;功能实用[滑稽][滑稽] 缺点就是UI简陋&#xff0c;功能稀少 第一张是首页&#xff0c;第二张是查看留言 第三张是留言列表(10秒自动刷新)&#xff0c;第四张是表白墙界面

小程序商城被盗刷,使用SCDN安全加速有用吗?

在电子商务蓬勃发展的今天&#xff0c;小程序商城因其便捷性和灵活性成为商家和消费者的新宠。然而&#xff0c;随着其普及&#xff0c;小程序商城的安全问题也日益凸显&#xff0c;尤其是盗刷现象频发&#xff0c;给商家和用户带来了巨大损失。面对这一挑战&#xff0c;是否可…

android13隐藏调节声音进度条下面的设置按钮

总纲 android13 rom 开发总纲说明 目录 1.前言 2.情况分析 3.代码修改 4.编译运行 5.彩蛋 1.前言 将下面的声音调节底下的三个点的设置按钮,隐藏掉。 效果如下 2.情况分析 查看布局文件 通过布局我们可以知道这个按钮就是 com.android.keyguard.AlphaOptimizedImageB…

火语言RPA流程组件介绍--变量赋值

变量赋值 &#x1f6a9;【组件功能】&#xff1a;对已定义的变量进行赋值操作。 支持对任意类型的变量进行赋值&#xff0c;赋值内容可以为字符串也可通过表达式进行计算运行后再赋值给指定变量。 配置预览 配置说明 变量名称 手动输入变量名称或点击输入框下拉选择已创建…

el-form的必填校验的星号*放在label的右边

1.el-form添加hide-required-asterisk <el-form :model"userInfoForm" label-width"80px" :inline"true" :rules"rules" ref"ruleForm"label-position"top"hide-required-asterisk>2.添加样式 .el-form-it…

美国政府紧急应对三星Galaxy手机安全漏洞

一、美国政府紧急通知更新三星Galaxy手机系统 美国政府近日发布紧急通知&#xff0c;要求联邦政府雇员在8月28日前更新三星Galaxy手机系统&#xff0c;否则将面临禁止使用这些设备的后果。这是继7月针对Pixel手机用户的类似要求之后的又一次紧急行动。此次事件的导火索是谷歌发…