当前位置: 首页 > news >正文

浅谈反射机制

1. 何为反射?

反射(Reflection)机制指的是程序在运行的时候能够获取自身的信息。具体来说,反射允许程序在运行时获取关于自己代码的各种信息。如果知道一个类的名称或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法参数等等所有信息)找出来。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。简单来说,就是面向对象看待一个类,即以面向对象的思想来抽象一个类。

反射是一种强大的功能,广泛应用于框架设计、依赖注入、单元测试和动态代理等领域。然而,由于反射会绕过编译时的类型安全检查,所以使用不当可能会导致更高的运行时错误几率和性能开销。因此,在使用反射时需要格外谨慎,以避免潜在的风险。

2. 反射的意义所在?

  1. 通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类。
  2. 使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法。
  3. 反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中。

不过反射也存在明显的缺点:使用反射性能较低,需要解析字节码,且如果将内存中的对象进行解析,相对不安全,会破坏封装性。

3. 通过反射实例化对象

在Java中,可以通过反射获取类的构造器、方法、字段等信息:

class Test {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {// 下面这段代码是以反射机制的方式创建对象。// 通过反射机制,获取Class,通过Class来实例化对象Class c = Class.forName("com.reflectBean.User");// newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。// 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!Object obj = c.newInstance();Method method = c.getMethod("myMethod");method.invoke(obj);}
}

4. 获取Class类的三种方式

在Java编程中,获取 Class 对象的三种常用方式如下:

1. 通过类名的静态属性 class: 这是获取 Class 对象最简单的方法,适用于已知编译时类型的情况。

Class<MyClass> clazz = MyClass.class;

2. 通过对象的实例方法 getClass: 这是在运行时获取一个对象的 Class 对象的方法,适用于已知一个实例化对象的情况。

MyClass obj = new MyClass();
Class<? extends MyClass> clazz = obj.getClass();

3. 通过类名的字符串 forName: 这是动态加载类的一种方式,特别有用在类名只有在运行时才能确定的情况下。

try {Class<?> clazz = Class.forName("com.reflectBean.User");
} catch (ClassNotFoundException e) {e.printStackTrace();
}

5. 常用的Class类的方法

Class 类在 Java 中定义了大量的方法,可以用来反射性地获取类的各种信息或进行操作。不过需要注意的是,在使用反射进行私有成员访问时,需要设置相应的访问权限,如 setAccessible(true)。以下是一些常用的方法:

1. 类信息获取方法

  • getName():返回完整类名带包名。

  • getSimpleName():获取类的简单名称。

  • getCanonicalName():获取类的规范名称。

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

  • getModifiers():获取类的修饰符(如 public, abstract, final 等)。

2. 构造函数相关方法

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

  • getConstructors():获取所有公共构造函数。

  • getDeclaredConstructor(Class<?>... parameterTypes):获取指定参数类型的任意(包括私有)构造函数。

  • getDeclaredConstructors():获取所有任意(包括私有)构造函数。

3. 方法相关方法

  • getMethod(String name, Class<?>... parameterTypes):获取指定名称和参数类型的公共方法。
  • getMethods():获取所有公共方法,包括从父类继承的方法。
  • getDeclaredMethod(String name, Class<?>... parameterTypes):获取指定名称和参数类型的任意方法。
  • getDeclaredMethods():获取所有任意方法(包括私有)。

4. 字段(成员变量)相关方法

  • getField(String name):获取指定名称的公共字段。
  • getFields():获取所有公共字段。
  • getDeclaredField(String name):获取指定名称的任意字段。
  • getDeclaredFields():获取所有任意字段(包括私有)。

5. 类层次结构相关方法

  • getSuperclass():获取父类。
  • getInterfaces():获取实现的接口。
  • isAssignableFrom(Class<?> cls):判断当前类或接口是否可以从指定类型的对象赋值(即能否进行类型转换)。

6. 实例创建方法

  • newInstance():创建类的实例,需要无参构造函数。

7. 其他方法

  • getAnnotations():获取类上的注解。
  • isAnnotation():判断类是否是注解类型。
  • isInterface():判断是否为接口。
  • isArray():判断是否为数组。
  • isPrimitive():判断是否为基本数据类型。
  • isInstance(Object obj):判断给定对象是否为该 Class 的实例。

6. 获取Field的四种方式

在Java中,可以通过Class对象获取某个类的字段(Field),Field类代表类的成员变量。获取 Field的几种常用方式如下:

1. 通过字段名获取公共字段 (public 属性):

try {Class<?> clazz = Class.forName("com.reflectBean.User");Field field = clazz.getField("userName");// 对 field 进行操作// ...} catch (NoSuchFieldException | ClassNotFoundException e) {e.printStackTrace();
}

2. 获取所有公共字段 (public 属性):

try {Class<?> clazz = Class.forName("com.reflectBean.User");Field[] fields = clazz.getFields();for (Field field : fields) {// 对每个 field 进行操作// ...    }
} catch (ClassNotFoundException e) {e.printStackTrace();
}

3. 通过字段名获取任何字段(包括私有、保护和包访问属性):

try {Class<?> clazz = Class.forName("com.reflectBean.User");Field field = clazz.getDeclaredField("password");// 允许访问私有字段field.setAccessible(true);  // 对 field 进行操作,比如设置可访问性field.setAccessible(true);
} catch (NoSuchFieldException | ClassNotFoundException e) {e.printStackTrace();
}

4. 获取所有字段(包括私有、保护和包访问属性):

try {Class<?> clazz = Class.forName("com.reflectBean.User");Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {// 对每个 field 进行操作,比如设置可访问性field.setAccessible(true);}
} catch (ClassNotFoundException e) {e.printStackTrace();
}

7. 常用的Field类的方法

在Java中,Field类提供了许多方法,用于获取和操作类的字段(成员变量)。以下是一些常用的方法:

1. 获取字段信息的方法

  • getName():返回字段的名称。
  • getType():返回表示字段类型的 Class 对象。
  • getGenericType():返回表示字段的 Type 对象,包括泛型类型信息。
  • getModifiers():返回字段的修饰符整数编码(使用 Modifier 类中的方法可以解码)。

2. 访问和修改字段值的方法

  • get(Object obj):从指定对象中获取该字段的值。
  • getByte(Object obj):从指定对象中获取该字段的值(byte类型)。
  • set(Object obj, Object value):将指定对象的该字段设置为新的值。

3. 访问控制

  • setAccessible(boolean flag):设置字段的可访问性。即使字段是私有的,通过设置可访问性也可以访问它。

8. 获取Method的四种方式

在Java中,可以通过反射机制获取类的方法(Method)对象。以下是几种常用的方法获取方式:

1. 通过方法名和参数类型获取公共方法

try {// 获取类的Class对象Class<?> clazz = Class.forName("com.reflectBean.User");// 通过方法名和参数类型获取公共方法Method method = clazz.getMethod("publicMethod", String.class);// 调用方法method.invoke(null, "参数");} catch (Exception e) {e.printStackTrace();}

2. 获取所有公共方法

try {// 获取类的Class对象Class<?> clazz = Class.forName("com.reflectBean.User");// 获取所有公共方法Method[] methods = clazz.getMethods();// 遍历所有方法for (Method method : methods) {// 获取方法名String methodName = method.getName();// 判断方法名是否为getNameif (methodName.equals("getName")) {// 执行getName方法Object result = method.invoke(user);System.out.println(result);}}} catch (Exception e) {e.printStackTrace();}

3. 通过方法名和参数类型获取任意方法(包括私有、保护和默认访问权限的方法)

try {// 获取类的Class对象Class<?> clazz = Class.forName("com.reflectBean.User");// 通过方法名和参数类型获取任意方法Method method = clazz.getDeclaredMethod("privateMethod", int.class);// 调用方法method.invoke(new com.reflectBean.User(), 100);// 允许访问私有方法method.setAccessible(true);} catch (Exception e) {e.printStackTrace();}

4. 获取所有的任意方法(包括私有、保护和默认访问权限的方法)

try {// 获取类的Class对象Class<?> clazz = Class.forName("com.example.MyClass");// 获取所有任意方法Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {// 对每个 method 进行操作// ...}} catch (Exception e) {e.printStackTrace();}

9. 常用的Method的方法

Method类在Java反射中提供了许多方法,这些方法可以用于获取方法的各类信息、调用方法以及操作注解等。以下是一些常用的Method类方法:

1. 获取方法信息的方法

  • String getName():获取方法的名称。
  • Class<?> getDeclaringClass():获取声明此方法的类或接口的Class对象。
  • Class<?> getReturnType():获取方法的返回类型。
  • Type getGenericReturnType():获取方法的泛型返回类型。
  • Class<?>[] getParameterTypes():获取方法的参数类型数组。
  • Type[] getGenericParameterTypes():获取方法的泛型参数类型数组。
  • int getParameterCount():获取方法的参数数量。
  • Class<?>[] getExceptionTypes():获取方法声明的异常类型数组。
  • Type[] getGenericExceptionTypes():获取方法声明的泛型异常类型数组。
  • int getModifiers():获取方法的修饰符,用于确定方法是public、private、protected、static等。
  • Annotation[][] getParameterAnnotations():获取方法的参数上的注解。
  • String toGenericString():返回描述方法的字符串,包括泛型信息。

2. 调用方法

  • Object invoke(Object obj, Object... args):调用此Method对象表示的底层方法。

3. 注解相关的方法

  • <T extends Annotation> T getAnnotation(Class<T> annotationClass):获取指定类型的注解。
  • Annotation[] getAnnotations():获取此方法上存在的所有注解。
  • Annotation[] getDeclaredAnnotations():获取直接存在于此方法上的所有注解。
  • <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass):获取直接存在于此方法上的指定类型的注解。
  • <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass):获取直接存在于此方法上的指定类型的所有注解。
  • <T extends Annotation> T getAnnotationsByType(Class<T> annotationClass):获取此方法上存在的指定类型的所有注解。
  • boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):判断此方法上是否存在指定类型的注解。

4. 设置和获取访问控制

  • void setAccessible(boolean flag):设置方法的可访问性。如果是 true,则强制使能此方法,即使它是私有的。
  • boolean isAccessible():判断此方法是否可以通过反射执行。

5. 其他常用方法

  • boolean isSynthetic():判断此方法是否是编译器生成的合成方法。
  • boolean isVarArgs():判断此方法是否接受可变数量的参数。

10. 实践出真知

好了,扯了那么久反射的概念和基础使用,接下来,结合反射的内容,我们来简单演示通过反射去实现一些基本业务。

10.1 如何通过反射获取和设置对象私有字段的值?

先捋清楚思路,获取和设置对象私有字段的值,大致可以分为四个步骤实现:

1. 获取对象的 Class 对象。
2. 通过反射获取私有字段 Field 对象。
3. 设置字段的可访问性为 true,以绕过 Java 语言访问检查。
4. 通过反射获取和设置字段的值。

那么接下来演示下代码的实现流程:

假设有一个包含私有字段的类:AccountBalance.class

public class AccountBalance {// 设置初始值为100private BigDecimal balance = new BigDecimal(100);// 默认构造函数public AccountBalance() {}// 打印字段值的方法public void printField() {System.out.println("当前的账户余额为: " + balance);}
}

接下来,我们来演示下怎么通过反射获取账户余额,然后变更私有字段:

public class Test {public static void main(String[] args) {try {// 创建 AccountBalance 对象实例AccountBalance account = new AccountBalance();// 获取 AccountBalance 的 Class 对象Class<?> clazz = account.getClass();// 获取私有字段Field privateField = clazz.getDeclaredField("balance");// 设置字段的可访问性为 trueprivateField.setAccessible(true);// 获取私有字段的值BigDecimal initBlance = (BigDecimal) privateField.get(account);System.out.println("最初的账号余额为: " + initBlance);// 设置私有字段的值privateField.set(account, new BigDecimal(50));// 验证字段值已经更新initBlance = (BigDecimal) privateField.get(account);System.out.println("本次扣除的账户余额为: " + initBlance);// 使用类的方法验证字段被正确修改account.printField();} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}
}

控制台输出:

10.2 如何用反射机制创建对象呢?

依旧是先整理下步骤,使用反射机制创建对象,大致可分为3个步骤:

1. 获取类的Class对象。
2. 通过Class对象获取构造方法(构造器)。注意,这里虽然可以通过Class对象的newInstance方法简单地创建一个类的实例,但是这种方式只能调用无参构造函数,故该实例不给予演示。
3. 使用构造方法创建类的实例。

还是假设我们有一个包含无参和有参数构造函数的类AccountBalance.class

public class AccountBalance {// 设置初始值为100private BigDecimal balance = new BigDecimal(100);// 默认构造函数public AccountBalance() {System.out.println("调用无参构造函数");}// 有参构造函数public AccountBalance(BigDecimal initialBalance) {this.balance = initialBalance;System.out.println("调用带参数的构造函数:初始化余额为 " + initialBalance);}// 打印字段值的方法public void printField() {System.out.println("当前的账户余额为: " + balance);}
}

使用Constructor.newInstance()创建对象并访问其方法

public void Test {public static void main(String[] args) {try {// 获取 AccountBalance 的 Class 对象Class<?> clazz = Class.forName("com.example.AccountBalance");// 获取有参构造函数Constructor<?> constructor = clazz.getConstructor(BigDecimal.class);// 使用构造函数创建实例并传递参数Object obj = constructor.newInstance(new BigDecimal(200));// 验证对象创建成功,通过调用方法Method printMethod = clazz.getMethod("printField");printMethod.invoke(obj);} catch (Exception e) {e.printStackTrace();}}}

10.3 如何反编译一个类的构造方法?

反编译一个类的构造方法,大致可以分为四个步骤实现:

1. 获取需要被反编译的类的Class对象

2. 获取类所有声明的构造方法

3. 循环遍历所有的构造方法

4. 获取每个构造方法的修饰符、参数类型并格式化输出

我们仍然以AccountBalance类为例进行说明。

public class AccountBalance {// 设置初始值为100private BigDecimal balance = new BigDecimal(100);// 默认构造函数public AccountBalance() {System.out.println("调用无参构造函数");}// 有参构造函数public AccountBalance(BigDecimal initialBalance) {this.balance = initialBalance;System.out.println("调用带参数的构造函数:初始化余额为 " + initialBalance);}// 打印字段值的方法public void printField() {System.out.println("当前的账户余额为: " + balance);}
}

进行反编译构造方法流程:

public void Test {public static void main(String[] args) {try {// 获取 AccountBalance 的 Class 对象Class<?> clazz = Class.forName("com.example.AccountBalance");// 获取所有声明的构造方法(包括私有构造方法)Constructor<?>[] constructors = clazz.getDeclaredConstructors();for (Constructor<?> constructor : constructors) {// 获取构造方法的修饰符String modifiers = Modifier.toString(constructor.getModifiers());// 获取构造方法的参数类型Class<?>[] parameterTypes = constructor.getParameterTypes();StringBuilder params = new StringBuilder();for (int i = 0; i < parameterTypes.length; i++) {params.append(parameterTypes[i].getSimpleName());if (i < parameterTypes.length - 1) {params.append(", ");}}// 打印构造方法的详细信息System.out.println(modifiers + " " + clazz.getSimpleName() + "(" + params + ") { }");}} catch (ClassNotFoundException e) {e.printStackTrace();}}}

10.4  给定一个类,如何获取这个类的基类以及实现的接口呢?

这种问题的思路,需要考虑两点:
1. 怎么获取该类的父类:这点可以使用Class提供的getSuperClass()方法来获取。

2. 怎么获取类的接口:这点可以使用Class提供的getInterfaces()方法获取实现的接口。

假设定义了以下类和接口:ChildClass.class 和 Parent.class、Car.java。

public class ChildClass extends ParentClass implements Car {}
public class ParentClass {}
public interface Car {
}

获取一个类的父类和实现的接口的具体示例:

public static void main(String[] args) throws ClassNotFoundException {try {// 获取 ChildClass 的 Class 对象Class<?> clazz = Class.forName("com.example.ChildClass");// 获取父类Class<?> superClass = clazz.getSuperclass();System.out.println("父类: " + superClass.getName());// 获取实现的接口Class<?>[] interfaces = clazz.getInterfaces();System.out.println("实现的接口:");for (Class<?> iface : interfaces) {System.out.println(iface.getName());}} catch (ClassNotFoundException e) {e.printStackTrace();}
}

11. 总结

反射机制是Java语言中一种强大的功能,它让我们能够在运行时进行一些本应只能在编译时完成的操作。这个功能的特点就是使得程序可以动态地检查和操作类、方法、字段等,从而带来了极大的灵活性。简单来说,反射机制使得开发人员能够编写更加灵活和动态的代码。举个例子,我们可以根据配置文件来动态创建对象、实现依赖注入、在运行时调用方法而不需要提前知道方法的名称。

然而,反射机制虽然给我们带来了好处,但也有一些弊端需要注意。首先,反射通常会比直接调用要慢,因为它会绕过一些编译时的优化。其次,由于反射机制允许操作私有成员,可能会破坏封装性和安全性。最后,使用反射的代码可读性降低,同时也更难以维护和调试。因此,在使用反射时需要谨慎考虑其影响。

相关文章:

浅谈反射机制

1. 何为反射&#xff1f; 反射&#xff08;Reflection&#xff09;机制指的是程序在运行的时候能够获取自身的信息。具体来说&#xff0c;反射允许程序在运行时获取关于自己代码的各种信息。如果知道一个类的名称或者它的一个实例对象&#xff0c; 就能把这个类的所有方法和变…...

解决obsidian加粗中文字体显示不突出的问题

加粗字体显示不突出的原因&#xff1a;默认字体的加粗版本本来就不突出 解决方法&#xff1a;改成显示突出的类型Microsoft YaHei UI 【效果】 修改前&#xff1a;修改后&#xff1a; 其他方法&#xff1a; 修改css&#xff08;很麻烦&#xff0c;改半天也不一定奏效&#…...

Shell echo命令

Shell echo命令 在Shell编程中,echo命令是一个常用的内置命令,用于在终端或控制台上显示文本或变量的值。它是与用户交互的一种基本方式,经常用于输出信息、创建文件内容或与脚本的其他部分进行通信。本文将详细介绍echo命令的用法、选项和实际应用示例。 基本用法 echo命…...

级联目标检测:构建高效目标识别的多阶段策略

标题&#xff1a;级联目标检测&#xff1a;构建高效目标识别的多阶段策略 级联目标检测&#xff08;Cascade Object Detection&#xff09;是一种多阶段的目标检测方法&#xff0c;它通过一系列逐渐细化的分类器来提高检测的准确性和效率。这种技术通常用于处理计算资源受限的…...

this指向问题以及如何改变指向

当在Vue.js中讨论"this"的指向问题时&#xff0c;有几个重要的方面需要考虑&#xff0c;特别是在组件化开发和异步操作中&#xff1a; 1. 普通函数 vs 箭头函数 在JavaScript中&#xff0c;普通函数和箭头函数对于"this"的处理方式有显著区别&#xff1a;…...

基于.NET开源游戏框架MonoGame实现的开源项目合集

前言 今天分享一些基于.NET开源游戏框架MonoGame实现的开源项目合集。 MonoGame项目介绍 MonoGame是一个简单而强大的.NET框架&#xff0c;使用C#编程语言可以创建桌面PC、视频游戏机和移动设备游戏。它已成功用于创建《怒之铁拳4》、《食肉者》、《超凡蜘蛛侠》、《星露谷物…...

spring boot + vue3+element plus 项目搭建

一、vue 项目搭建 1、创建 vue 项目 vue create vue-element说明&#xff1a;创建过程中可以选择路由&#xff0c;也可也可以不选择&#xff0c;可以通过 npm install 安装 vue 项目目录结构 说明&#xff1a;api 为自己创建的文件夹&#xff0c;router 选择路由模块会自动…...

linux之管道重定向

管道与重定向 一、重定向 将原输出结果存储到其他位置的过程 标准输入、标准正确输出、标准错误输出 ​ 进程在运行的过程中根据需要会打开多个文件&#xff0c;每打开一个文件会有一个数字标识。这个标识叫文件描述符。 进程使用文件描述符来管理打开的文件&#xff08;FD--…...

to_json 出现乱码的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

Java接口和类

package chapter04;public class Java22_Object_接口 {public static void main(String[] args) {// TODO 面向对象 - 接口// 所谓的接口&#xff0c;可以简单理解为规则、规范// 基本语法&#xff1a;interface 接口名称 { 规则属性&#xff0c;规则的行为 }// 接口其实是抽象…...

前端文件预览汇总

一、vue中预览word、excel、pdf&#xff1a; vue-office vue-office支持多种文件(docx、excel、pdf)预览的vue组件库&#xff0c;支持vue2/3&#xff0c;也支持非Vue框架的预览。 特点&#xff1a; 一站式&#xff1a;提供word(.docx)、pdf、excel(.xlsx, .xls)多种文档在线…...

银河麒麟V10 安装tigervncserver

银河麒麟V10 安装tigervncserver 银河麒麟V10安装tigervnc-server步骤&#xff1a; 提示&#xff0c;本安装环境&#xff1a;arm飞腾2000&#xff0c;主机开机进入root用户模式。 1、安装server安装包 #rpm -i tigervnc-server-1.10.1-5.p05.ky10.aarch64.rpm 2、控制台输入 …...

SKM Power*Tools 10.0

SKM Power*Tools 10.0是功能强大的电气电力系统分析设计解决方案&#xff01;综合软件提供强大的功能和领先的技术&#xff0c;在检查、计算、负载分配、流量、瞬态稳定性等多个方面提供领先的支持&#xff0c;可对不同的安全设备、系统进行评估分析和比较&#xff0c;使用 Pow…...

查看视频时间基 time_base

时间基、codec, 分辨率&#xff0c;音频和视频的都一样&#xff0c;才可以直接使用ffmpeg -f concat -i file.txt 方式合并。 On Thu, Dec 03, 2015 at 21:54:53 0200, redneb8888 wrote: I am looking for a way to find the time base of a stream (video or audio), $ ffpr…...

数据结构 —— 最小生成树

数据结构 —— 最小生成树 什么是最小生成树Kruskal算法Prim算法 今天我们来看一下最小生成树&#xff1a; 我们之前学习的遍历算法并没有考虑权值&#xff0c;仅仅就是遍历结点&#xff1a; 今天的最小生成树要满足几个条件&#xff1a; 考虑权值所有结点联通权值之和最小无环…...

初学Spring之 JavaConfig 实现配置

使用 Java 方式配置 Spring 写个实体类&#xff1a; Component 表示这个类被 Spring 接管了&#xff0c;注册到了容器中 package com.demo.pojo;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;Component //…...

在Java项目中实现实时日志分析

在Java项目中实现实时日志分析 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 随着互联网应用的发展&#xff0c;实时日志分析成为了保证系统稳定性、性能优化…...

Git基础知识与常用命令指南

这是一个Git基础知识和常用命令的简要指南,涵盖了日常开发中最常用的操作。你可以将这个指南保存下来,作为日常工作的参考。 目录 基础篇1. Git基本概念2. 配置Git3. 创建仓库4. 基本的工作流程5. 分支操作6. 查看历史7. 撤销更改8. 远程仓库操作 Git进阶知识与技巧指南1. 分…...

第8章:Electron 剪贴版和消息通知

在本章中&#xff0c;我们将介绍如何在Electron应用中与操作系统进行集成。这些操作包括剪贴板操作、通知系统、原生对话框等功能。 8.1 剪贴板操作 Electron 提供了 clipboard 模块&#xff0c;允许我们在应用中访问和操作剪贴板内容。以下是一些基本的剪贴板操作示例。 8.…...

Android zygote访谈录

戳蓝字“牛晓伟”关注我哦&#xff01; 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章&#xff0c;技术文章也可以有温度。 本文摘要 本文以访谈的方式来带大家了解zygote进程&#xff0c;了解zygote进程是啥&#xff1f;它的作用是啥&#xff1f;它是如何一步…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...