Java注解以及自定义注解
Java注解以及自定义注解
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为
我们提供的元注解和相关定义注解的语法。
1、注解
1.1 注解的官方定义
注解是一种元数据形式。即注解是属于java的一种数据类型,和类、接口、数组、枚举类似。
注解用来修饰,类、方法、变量、参数、包。
注解不会对所修饰的代码产生直接的影响。
1.2 注解的使用范围
注解有许多用法,其中有:为编译器提供信息 - 注解能被编译器检测到错误或抑制警告。编译时和部署时的处理 -
软件工具能处理注解信息从而生成代码,XML文件等等。运行时的处理 - 有些注解在运行时能被检测到。
2、元注解
一个最最基本的注解定义就只包括了两部分内容:1、注解的名字;2、注解包含的类型元素。但是,我们在使用
JDK自带注解的时候发现,有些注解只能写在方法上面(比如@Override);有些却可以写在类的上面(比如
@Deprecated)。当然除此以外还有很多细节性的定义,那么这些定义该如何做呢?接下来就该元注解出场了!
元注解:专门修饰注解的注解。它们都是为了更好的设计自定义注解的细节而专门设计的。Java5.0定义了4个标准
的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。
Java5.0 定义的元注解:
1、@Target
2、@Retention
3、@Documented
4、@Inherited
这些类型和它们所支持的类在java.lang.annotation
包中可以找到。下面我们看一下每个元注解的作用和相应
分参数的使用说明。
2.1 @Target
@Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、
Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、
catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
作用:用于描述注解的使用范围(即被描述的注解可以用在什么地方)
取值(ElementType)有:
1、CONSTRUCTOR
:用于描述构造器
2、FIELD
:用于描述域
3、LOCAL_VARIABLE
:用于描述局部变量
4、METHOD
:用于描述方法
5、PACKAGE
:用于描述包
6、PARAMETER
:用于描述参数
7、TYPE
:用于描述类、接口(包括注解类型) 或enum声明
它使用一个枚举类型定义如下:
public enum ElementType {/** 类,接口(包括注解类型)或枚举的声明 */TYPE,/** 属性的声明 */FIELD,/** 方法的声明 */METHOD,/** 方法形式参数声明 */PARAMETER,/** 构造方法的声明 */CONSTRUCTOR,/** 局部变量声明 */LOCAL_VARIABLE,/** 注解类型声明 */ANNOTATION_TYPE,/** 包的声明 */PACKAGE,TYPE_PARAMETER,TYPE_USE
}
使用实例:
package com.test3;import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
public @interface Table {/*** 数据表名称注解,默认值为类名称* @return*/public String tableName() default "className";
}
package com.test3;import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
public @interface NoDBColumn {
}
package com.test3;import java.lang.annotation.ElementType;
import java.lang.annotation.Target;//@CherryAnnotation被限定只能使用在类、接口或方法上面
@Target(value = {ElementType.TYPE, ElementType.METHOD})
public @interface CherryAnnotation {String name();int age() default 18;int[] array();
}
注解Table
可以用于注解类、接口(包括注解类型) 或enum声明,而注解NoDBColumn
仅可用于注解类的成员变
量。
2.2 @Retention
@Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。
注解的生命周期有三个阶段:1、Java源文件阶段;2、编译到class文件阶段;3、运行期阶段。同样使用了
RetentionPolicy 枚举类型定义了三个阶段:
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即被描述的注解在什么范围内有效)
取值(RetentionPoicy)有:
1、SOURCE
:在源文件中有效(即源文件保留)
2、CLASS
:在class文件中有效(即class保留)
3、RUNTIME
:在运行时有效(即运行时保留)
Retention meta-annotation类型有唯一的value作为成员,它的取值来自
java.lang.annotation.RetentionPolicy
的枚举类型值。
public enum RetentionPolicy {// 注解将被编译器忽略掉SOURCE,// 注解将被编译器记录在class文件中,但在运行时不会被虚拟机保留,这是一个默认的行为CLASS,// 注解将被编译器记录在class文件中,而且在运行时会被虚拟机保留,因此它们能通过反射被读取到RUNTIME
}
我们再详解一下:
如果一个注解被定义为RetentionPolicy.SOURCE
,则它将被限定在Java源文件中,那么这个注解即不会参与编
译也不会在运行期起任何作用,这个注解就和一个注释是一样的效果,只能被阅读Java文件的人看到;
如果一个注解被定义为RetentionPolicy.CLASS
,则它将被编译到Class文件中,那么编译器可以在编译时根据
注解做一些处理动作,但是运行时JVM(Java虚拟机)会忽略它,我们在运行期也不能读取到;
如果一个注解被定义为RetentionPolicy.RUNTIME
,那么这个注解可以在运行期的加载阶段被加载到Class对象
中。那么在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,
从而执行不同的程序代码段。我们实际开发中的自定义注解几乎都是使用的RetentionPolicy.RUNTIME
;在默认
的情况下,自定义注解是使用的RetentionPolicy.CLASS
。
具体实例如下:
package com.test3;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {public String name() default "fieldName";public String setFuncName() default "setField";public String getFuncName() default "getField";public boolean defaultDBValue() default false;
}
Column注解的的RetentionPolicy的属性值是RUNTIME,这样注解处理器可以通过反射,获取到该注解的属性
值,从而去做一些运行时的逻辑处理。
2.3 @Documented
@Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中,因此可以
被例如javadoc此类的工具文档化。
Documented是一个标记注解,没有成员。
package com.test3;import java.lang.annotation.*;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column1 {public String name() default "fieldName";public String setFuncName() default "setField";public String getFuncName() default "getField";public boolean defaultDBValue() default false;
}
2.4 @Inherited
@Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注
解。@Inherited注解只对那些@Target被定义为ElementType.TYPE
的自定义注解起作用。
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了
@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,
方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这
种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查
将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
实例代码:
package com.test3;import java.lang.annotation.Inherited;@Inherited
public @interface Greeting {public enum FontColor {BULE, RED, GREEN};String name();FontColor fontColor() default FontColor.GREEN;
}
注解的继承依赖如下一个因素:
1、首先要想Annotation
能被继承,需要在注解定义的时候加上@Inherited
,并且如果要被反射应用的话,还
需要@Retention(RetentionPolicy.RUNTIME)
标识。
2、JDK文档中说明的是:只有在类上应用Annotation
才能被继承,而实际应用结果是:除了类上应用的
Annotation
能被继承外,没有被重写的方法的Annotation
也能被继承。
3、当方法被重写后,Annotation
不会被继承。
4、Annotation
的继承不能应用在接口上。
3、自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细
节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声
明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、
Class、String、enum)。可以通过default来声明参数的默认值。
3.1 定义注解格式
public @interface 注解名 {定义体}
public @interface CherryAnnotation {
}
根据我们在自定义类的经验,在类的实现部分无非就是书写构造、属性或方法。但是,在自定义注解中,其实现
只能定义一个东西:注解类型元素(annotation type element)。语法:
public @interface CherryAnnotation {public String name();public int age();public int[] array();
}
public @interface CherryAnnotation {public String name();public int age() default 18;public int[] array();
}
3.2 注解参数的可支持数据类型
1、所有基本数据类型(int,float,boolean,byte,double,char,long,short
)
2、String
类型
3、Class
类型
4、enum
类型
5、Annotation
类型
6、以上所有类型的数组
注解里面定义的是:注解类型元素!
3.3 定义注解类型元素时需要注意如下几点
1、只能用public或默认(default)这两个访问权修饰,例如String value();
这里把方法设为default默认类型。
2、参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,
Enum,Class,annotations等数据类型,以及这一些类型的数组。
3、如果只有一个参数成员,最好把参数名称设为value
,后加小括号。
4、()
不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法。
5、default
代表默认值,值必须和第2点定义的类型一致。
6、如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
可以看出,注解类型元素的语法非常奇怪,即又有属性的特征(可以赋值),又有方法的特征(打上了一对括
号)。但是这么设计是有道理的,我们在后面的章节中可以看到:注解在定义好了以后,使用的时候操作元素类型
像在操作属性,解析的时候操作元素类型像在操作方法。
3.4 简单的自定义注解和使用注解实例
package com.test;import java.lang.annotation.*;/*** 水果名称注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {String value() default "";
}
package com.test;import java.lang.annotation.*;/*** 水果颜色注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {/*** 颜色枚举*/public enum Color {BULE, RED, GREEN};/*** 颜色属性** @return*/Color fruitColor() default Color.GREEN;}
package com.test;public class Apple {@FruitName("Apple")private String appleName;@FruitColor(fruitColor = FruitColor.Color.RED)private String appleColor;public void setAppleColor(String appleColor) {this.appleColor = appleColor;}public String getAppleColor() {return appleColor;}public void setAppleName(String appleName) {this.appleName = appleName;}public String getAppleName() {return appleName;}
}
3.5 注解元素的默认值
注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值
不可为null。因此,使用空字符串或0作为默认值是一种常用的做法。这个约束使得处理器很难表现一个元素的存
在或缺失的状态,因为每个注解的声明中,所有元素都存在,并且都具有相应的值,为了绕开这个约束,我们只能
定义一些特殊的值,例如空字符串或者负数,一次表示某个元素不存在,在定义注解时,这已经成为一个习惯用
法。
package com.test;import java.lang.annotation.*;/*** 水果供应者注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {/*** 供应商编号** @return*/public int id() default -1;/*** 供应商名称** @return*/public String name() default "";/*** 供应商地址** @return*/public String address() default "";
}
3.6 特殊语法
特殊语法一
如果注解本身没有注解类型元素,那么在使用注解的时候可以省略()
,直接写为:@注解名
,它和标准语法
@注解名()
等效!
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
@Documented
public @interface FirstAnnotation {
}
//等效于 @FirstAnnotation()
@FirstAnnotation
public class JavaBean{
}
特殊语法二
如果注解本身只有一个注解类型元素,而且命名为value,那么在使用注解的时候可以直接使用:
@注解名(注解值)
,其等效于:@注解名(value = 注解值)
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
@Documented
public @interface SecondAnnotation {String value();
}
//等效于 @SecondAnnotation(value = "this is second annotation")
@SecondAnnotation("this is annotation")
public class JavaBean{
}
特殊用法三
如果注解中的某个注解类型元素是一个数组类型,在使用时又出现只需要填入一个值的情况,那么在使用注解时可
直接写为:@注解名(类型名 = 类型值)
,它和标准写法:@注解名(类型名 = {类型值})
等效!
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
@Documented
public @interface ThirdAnnotation {String[] name();
}
//等效于 @ThirdAnnotation(name = {"this is third annotation"})
@ ThirdAnnotation(name = "this is third annotation")
public class JavaBean{
}
特殊用法四
如果一个注解的@Target是定义为Element.PACKAGE,那么这个注解是配置在package-info.java
中的,而不能
直接在某个类的package代码上面配置。
上面三节定义了注解,并在需要的时候给相关类,类属性加上注解信息,如果没有响应的注解信息处理流程,注解
可以说是没有实用价值。如何让注解真真的发挥作用,主要就在于注解处理方法,下一步我们将学习注解信息的获
取和处理!
4、自定义注解的配置使用
基于上一节,已对注解有了一个基本的认识:注解其实就是一种标记,可以在程序代码中的关键节点(类、方法、
变量、参数、包)上打上这些标记,然后程序在编译时或运行时可以检测到这些标记从而执行一些特殊操作。因此
可以得出自定义注解使用的基本流程:
第一步,定义注解——相当于定义标记;
第二步,配置注解——把标记打在需要用到的程序代码中;
第三步,解析注解——在编译期或运行时检测到标记,并进行特殊操作。
4.1 在具体的Java类上使用注解
首先,定义一个注解和一个供注解修饰的简单Java类。
package com.test1;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD})
@Documented
public @interface CherryAnnotation {String name();// 类型元素int age() default 18;int[] score();
}
package com.test1;public class Student {public void study(int times) {for (int i = 0; i < times; i++) {System.out.println("Good Good Study, Day Day Up!");}}
}
简单分析下:
CherryAnnotation的@Target定义为ElementType.METHOD,那么它书写的位置应该在方法定义的上方,即:
public void study(int times)之上。由于我们在CherryAnnotation中定义的有注解类型元素,而且有些元素是没有
默认值的,这要求我们在使用的时候必须在标记名后面打上(),并且在()内以“元素名=元素值“的形式挨个填上所有
没有默认值的注解类型元素(有默认值的也可以填上重新赋值),中间用“,”号分割。
所以最终书写形式如下:
package com.test1;public class Student {@CherryAnnotation(name = "cherry-peng", age = 23, score = {99, 66, 77})public void study(int times) {for (int i = 0; i < times; i++) {System.out.println("Good Good Study, Day Day Up!");}}
}
4.2 自定义注解的运行时解析(反射操作获取注解)
这一节是使用注解的核心,读完此节即可明白,如何在程序运行时检测到注解,并进行一系列特殊操作!
只有当注解的保持力处于运行阶段,即使用@Retention(RetentionPolicy.RUNTIME)
修饰注解时,才能在JVM
运行时,检测到注解,并进行一系列特殊操作。
在运行期探究和使用编译期的内容(编译期配置的注解),要用到Java中的灵魂技术——反射!
Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器。
package com.test1;import java.lang.reflect.Method;/*** @author zhangshixing* @date 2021年11月01日 9:32*/
public class TestAnnotation {public static void main(String[] args){try {//获取Student的Class对象Class stuClass = Class.forName("com.test1.Student");//说明一下,这里形参不能写成Integer.class,应写为int.classMethod stuMethod = stuClass.getMethod("study",int.class);if(stuMethod.isAnnotationPresent(CherryAnnotation.class)){System.out.println("Student类上配置了CherryAnnotation注解!");//获取该元素上指定类型的注解CherryAnnotation cherryAnnotation = stuMethod.getAnnotation(CherryAnnotation.class);System.out.println("name: " + cherryAnnotation.name() + ", age: " + cherryAnnotation.age()+ ", score: " + cherryAnnotation.score()[0]);}else{System.out.println("Student类上没有配置CherryAnnotation注解!");}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}}
}
# 程序输出
Student类上配置了CherryAnnotation注解!
name: cherry-peng, age: 23, score: 99
4.3 注解处理器类库(java.lang.reflect.AnnotatedElement)
Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。除此之外,Java
在java.lang.reflect
包下新增了AnnotatedElement
接口,该接口代表程序中可以接受注解的程序元素,该接
口主要有如下几个实现类:
Class
:类定义
Constructor
:构造器定义
Field
:类的成员变量定义
Method
:类的方法定义
Package
:类的包定义
java.lang.reflect
包下主要包含一些实现反射功能的工具类,实际上,java.lang.reflect 包所有提供的反射API
扩充了读取运行时Annotation信息的能力。当一个Annotation类型被定义为运行时的Annotation后,该注解才能
是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。
AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了
某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下四个个方法来访问Annotation信息:
isAnnotationPresent(Class<? extends Annotation> annotationClass)
方法是专门判断该元素上是否配
置有某个指定的注解;
getAnnotation(Class<A> annotationClass)
方法是获取该元素上指定的注解。之后再调用该注解的注解类型
元素方法就可以获得配置时的值数据;如果该类型注解不存在,则返回null。
反射对象上还有一个方法getAnnotations()
,该方法可以获得该对象身上配置的所有的注解。它会返回给我们
一个注解数组,需要注意的是该数组的类型是Annotation类型,这个Annotation是一个来自于
java.lang.annotation
包的接口。
Annotation[] getDeclaredAnnotations()
:返回直接存在于此元素上的所有注解。与此接口中的其他方法不
同,该方法将忽略继承的注解。(如果没有注解直接存在于此元素上,则返回长度为零的一个数组)。该方法的调
用者可以随意修改返回的数组;这不会对其它调用者返回的数组产生任何影响。
如果我们要获得的注解是配置在方法上的,那么我们要从Method对象上获取;如果是配置在属性上,就需要从该
属性对应的Field对象上去获取,如果是配置在类型上,需要从Class对象上去获取。总之在谁身上,就从谁身上去
获取!
一个简单的注解处理器
/***********注解声明***************/package com.test2;import java.lang.annotation.*;/*** 水果名称注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {String value() default "";
}
package com.test2;import java.lang.annotation.*;/*** 水果颜色注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {/*** 颜色枚举** @author peida*/public enum Color {BULE, RED, GREEN};/*** 颜色属性** @return*/Color fruitColor() default Color.GREEN;}
package com.test2;import java.lang.annotation.*;/*** 水果供应者注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {/*** 供应商编号** @return*/public int id() default -1;/*** 供应商名称** @return*/public String name() default "";/*** 供应商地址** @return*/public String address() default "";
}
/***********注解使用***************/package com.test2;public class Apple {@FruitName("Apple")private String appleName;@FruitColor(fruitColor = FruitColor.Color.RED)private String appleColor;@FruitProvider(id = 1, name = "陕西红富士集团", address = "陕西省西安市延安路89号红富士大厦")private String appleProvider;public void setAppleColor(String appleColor) {this.appleColor = appleColor;}public String getAppleColor() {return appleColor;}public void setAppleName(String appleName) {this.appleName = appleName;}public String getAppleName() {return appleName;}public void setAppleProvider(String appleProvider) {this.appleProvider = appleProvider;}public String getAppleProvider() {return appleProvider;}public void displayName() {System.out.println("水果的名字是:苹果");}
}
/***********注解处理器***************/package com.test2;import java.lang.reflect.Field;public class FruitInfoUtil {public static void getFruitInfo(Class<?> clazz) {String strFruitName = " 水果名称:";String strFruitColor = " 水果颜色:";String strFruitProvicer = "供应商信息:";Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(FruitName.class)) {FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);strFruitName = strFruitName + fruitName.value();System.out.println(strFruitName);} else if (field.isAnnotationPresent(FruitColor.class)) {FruitColor fruitColor = (FruitColor) field.getAnnotation(FruitColor.class);strFruitColor = strFruitColor + fruitColor.fruitColor().toString();System.out.println(strFruitColor);} else if (field.isAnnotationPresent(FruitProvider.class)) {FruitProvider fruitProvider = (FruitProvider) field.getAnnotation(FruitProvider.class);strFruitProvicer = " 供应商编号:" + fruitProvider.id() + " 供应商名称:" + fruitProvider.name() + " 供应商地址:" + fruitProvider.address();System.out.println(strFruitProvicer);}}}
}
/***********输出结果***************/package com.test2;public class FruitRun {/*** @param args*/public static void main(String[] args) {FruitInfoUtil.getFruitInfo(Apple.class);}}
# 程序输出水果名称:Apple水果颜色:RED供应商编号:1 供应商名称:陕西红富士集团 供应商地址:陕西省西安市延安路89号红富士大厦
相关文章:

Java注解以及自定义注解
Java注解以及自定义注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为 我们提供的元注解和相关定义注解的语法。 1、注解 1.1 注解的官方定义 注解是一种元数据形式。…...

[开学季]ChatPaper全流程教程
文章目录 1. 粗筛:论文全文总结1.1 使用步骤: 1.2 功能描述:2. 论文问答:2. 精读:学术版GPT的论文翻译2.0 论文精读的正确姿势2.1 使用场景1:arxiv论文完美翻译2.2 本地PDF全文翻译:2.3 关于免费…...

Spring学习笔记——4
Spring学习笔记——4 一、基于AOP的声明式事务控制1.1、Spring事务编程概述1.2、搭建测试环境1.3、基于XML声明式事务控制1.4、基于注解声明式事务控制 二、Spring整合web环境2.1、JavaWeb三大组件作用及其特点2.2、Spring整合web环境的思路及实现2.3、Spring的Web开发组件spri…...
Python数据科学入门
推荐:使用 NSDT场景编辑器 快速搭建3D应用场景 来自不同角色的人都希望保住自己的工作,因此他们将致力于发展自己的技能以适应当前的市场。这是一个竞争激烈的市场,我们看到越来越多的人对数据科学产生兴趣;该行业有数千门在线课程、训练营和…...
Ubuntu 22.04 编译 DPDK 19.11 igb_uio 和 kni 报错解决办法
由于 Ubuntu22.04 内核版本和gcc版本比较高,在编译dpdk时会报错。 我使用的编译命令是: make install Tx86_64-native-linuxapp-gcc主要有以下几个错误: 1.error: this statement may fall through Build kernel/linux/igb_uioCC [M] /roo…...
Android Studio.exe 下载 2023 最新更新,网盘下载
方便大家下载, 放到了网盘上,自己也保留一份。(最前面是最新版本的,慎用, 会有bug什么的) 个人使用4.2版本的,感觉够用稳定,其他版本有莫名奇妙的bug,让人头大࿰…...

element的el-select给下拉框添加背景
第一步 :popper-append-to-body"false" <el-selectv-model"value"placeholder"请选择":popper-append-to-body"false"><el-optionv-for"item in options":key"item.value":label"item.label&quo…...
正确理解党籍和党龄;入党和转正时间
总的来说党籍、党龄、入党时间、转正时间在性质和时间阶段上均有所区别。 党籍:是指党员资格。经支部党员大会讨论,被批准为预备党员之日起,就有了党籍。若被取消预备党员资格、劝退除名、自行脱党、开除党籍的,就失去了党籍。 …...
C语言基础:printf 函数介绍;以及常用四种常用的数据类型
printf 函数介绍 #include <stdio.h> int main() { /* * %c:字符 ; %d:带符号整数; %f: 浮点数; %s: 一串字符; */ int age21; printf(“hello %s,you are %d years old\n”,“Bob”,age); int i 10; double f96.20; printf(“student number%3d,score%f\n”…...

【LeetCode-中等题】209. 长度最小的子数组
文章目录 题目方法一:滑动窗口:方法二: 题目 方法一:滑动窗口: 参考图解动画:长度最小的子数组 class Solution { //方法一:滑动窗口public int minSubArrayLen(int target, int[] nums) {int n nums.l…...

比较聚合模型实战文本匹配
引言 本文我们采用比较聚合模型来实现文本匹配任务。 数据准备 数据准备包括 构建词表(Vocabulary)构建数据集(Dataset) 本次用的是LCQMC通用领域问题匹配数据集,它已经分好了训练、验证和测试集。 我们通过pandas来加载一下。 import pandas as pdtrain_df …...
LA@二次型@标准化相关原理和方法
文章目录 标准化方法正交变换法🎈求矩阵的特征值求各特征值对应的线性无关特征向量组正交化各个向量组 配方法步骤例例 初等变换法原理总结初等变换法的步骤例 标准化方法 正交变换法🎈 二次型可标准化定理的证明过程给出使用二次型标准化的步骤 该方法…...

Git与IDEA: 解决`dev`分支切换问题及其背后原因 为何在IDEA中无法切换到`dev`分支?全面解析!
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

什么是JavaScript中的严格模式(strict mode)?应用场景是什么?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 严格模式(Strict Mode):⭐ 使用场景⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…...

红外特征吸收峰特征总结(主要基团的红外特征吸收峰)
特此记录 anlog 2023年9月11日...
ChatGPT AIGC 完成关联分析散点图的应用
关联分析是数据分析中非常重要的一种技术手段,它能够帮助我们在大量数据中发现变量之间的关系和相互影响。在数据分析领域,关联分析被广泛应用于市场营销、销售预测、客户行为分析等领域。 关联分析的主要功能是通过挖掘数据中的关联规则,来发现数据集中事物之间的关联性。…...
CentOS7.6上实现Spring Boot(JAR包)开机自启
前言 Linux自启(或开机自启)指的是在Linux系统启动时自动运行特定的程序或脚本。当计算机启动时,操作系统会按照一定的顺序加载系统服务和配置,其中包括自动启动一些应用程序或服务。这些应用程序或服务会在系统启动后自动运行&a…...

Java开发之框架(spring、springmvc、springboot、mybatis)【面试篇 完结版】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、框架知识分布二、Spring1. spring-单例bean① 问题引入② 单例bean是线程安全的吗③ 问题总结④ 实战面试 2. spring-AOP① 问题引入② AOP记录操作日志③ …...
QT人脸识别知识
机器学习的作用:根据提供的图片模型通过算法生成数据模型,从而在其它图片中查找相关的目 标。 级联分类器:是用来人脸识别。 在判断之前,我们要先进行学习,生成人脸的模型以便后续识别使用。 人脸识别器:…...

熟悉Redis6
NoSQL数据库简介 技术发展 技术的分类 1、解决功能性的问题:Java、Jsp、RDBMS、Tomcat、HTML、Linux、JDBC、SVN 2、解决扩展性的问题:Struts、Spring、SpringMVC、Hibernate、Mybatis 3、解决性能的问题:NoSQL、Java线程、Hadoop、Nginx…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

年度峰会上,抖音依靠人工智能和搜索功能吸引广告主
上周早些时候举行的第五届年度TikTok World产品峰会上,TikTok推出了一系列旨在增强该应用对广告主吸引力的功能。 新产品列表的首位是TikTok Market Scope,这是一个全新的分析平台,为广告主提供整个考虑漏斗的全面视图,使他们能够…...

如何使用CodeRider插件在IDEA中生成代码
一、环境搭建与插件安装 1.1 环境准备 名称要求说明操作系统Windows 11JetBrains IDEIntelliJ IDEA 2025.1.1.1 (Community Edition)硬件配置推荐16GB内存50GB磁盘空间 1.2 插件安装流程 步骤1:市场安装 打开IDEA,进入File → Settings → Plugins搜…...

RocketMQ 客户端负载均衡机制详解及最佳实践
延伸阅读:🔍「RocketMQ 中文社区」 持续更新源码解析/最佳实践,提供 RocketMQ 专家 AI 答疑服务 前言 本文介绍 RocketMQ 负载均衡机制,主要涉及负载均衡发生的时机、客户端负载均衡对消费的影响(消息堆积/消费毛刺等…...