Java “框架 = 注解 + 反射 + 设计模式” 之 注解详解

news2024/11/15 4:24:21

Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解

在这里插入图片描述

每博一文案

刹那间我真想令时光停住,好让我回顾自己,回顾失去的年华,缅怀哪个穿一身短小的连衣裙
和瘦窄的短衫的小女孩。让我追悔少年时代,我心灵的愚钝无知,它轻易地错过了我一生中本来
可以获得欢乐和幸福。
                             —————— 《平凡的世界》
                             
真的,如果痛苦不能改变生存,那还不如平静地将自己毁灭,毁灭,一切都毁灭了,
只有生命还在苟延残喘,这样的生命还有有什么存在的价值。
                            —————— 《平凡的世界》
                     

文章目录

  • Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解
    • 每博一文案
    • 1. 注解的概念
    • 2. 注解的作用
    • 3. 文档注释中的注解
    • 4. 自定义注解
      • 4.1 注解中的属性
      • 4.2 注解中属性为:数组的赋值
    • 5. JDK 内置的三个基本注解
      • 5.1 @Override: 限定重写父类方法, 该注解只能用于方法
      • 5.2 @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。
      • 5.3 @SuppressWarnings: 抑制编译器警告
    • 6. 元注解
      • 6.1 @Target
      • 6.2 @Retention
      • 6.3 @Documented
      • 6.4 @Inherited
    • 7. 通过反射获取到注解信息
    • 8. 总结:
    • 9. 最后:

1. 注解的概念

注解,一种元数据形式提供了一个不属于程序本身的程序的数据。注解对他们注解的代码的操作没有直接的影响。

注解有很多用途,其中:

  • 编译器的信息 - 编译器可以使用注解来检测错误或抑制警告。
  • 编译和部署时处理 - 软件工具可以处理注解信息以生成代码,XML 文件等。
  • 运行时处理 - 一些注解可以在运行时检查

JDK5.0 开始,Java增加了对元数据**(MetaData)** 的支持,也就是 Annotation 注解。

  • 注解: 其实就是代码里的 特殊标记 ,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用 注解,

程序员可以在不改变原有的逻辑的情况下,在源文件种嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或进行部署。

  • 注解: 可以像修饰符一样被使用,可以用于 修饰:包,类,构造器,方法,成员变量,参数,局部变量的声明 。这些信息被保存在 注解 Annotaion 的“ name = value” 键值对中。

  • JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如

    用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗 代码和XML配置等。

  • 未来的开发模式都是基于注解的,JPA 是基于注解的,Spring2.5 以上都是基于注解的,Hibernate3.x 以后也是基于注解的,

现在Struts2 有一部分也是基于注解的了。注解是一种趋势,一定程度上可以说:框架 = 注解 + 反射 + 设计模式

2. 注解的作用

JVM 的角度看,注解本身对代码逻辑没有任何影响,如何使用注解完全由工具决定。

Java的注解可以分为三类:

  • 第一类:是由编译器使用的注解:换句话说就是给编译器看的,不是给 JVM 看的。例如:
    • @Override : 让编译器检查该方法是否正确的实现了 重写操作。
    • @Deprecated : 表示所修饰的元素(类,方法等)已过时了,不建议使用它了。
    • @SuppressWarnings: 告诉编译器忽略此处代码产生的警告。
  • 第二类: 是由工具处理 .class 文件使用的注解,比如有些工具会在加载 class 的时候,对 class 做动态修改,实现一些特殊的功能。这类注解会被编译进入到 .class 文件,但加载结束后并不会存在于内存中。这类注解只被一些底层使用,一般我们不必自己处理。
  • 第三类: 是在程序运行期间能够读取的注解,它们在加载后一直存在于 JVM 中,这也是最常用的注解。例如:一个配置了@PostConstruct 的方法会在调用构造方法后自动被调用,(这是Java代码读取该注解实现的功能,JVM 并不会识别该注解)。

3. 文档注释中的注解

在这里插入图片描述

在这里插入图片描述

  • @author 标明开发该类模块的作者,多个作者之间使用,分割。
  • @version 标明该类的模块的版本。
  • @see 参考转向,也就是相关类的主题。
  • @since 从哪个版本开始增加的。
  • @param 对方法中某参数的说明,如果没有参数就不能写。
  • @return 对方法返回值的说明,如果方法的返回值类型是 void 就不能写
  • @exception 对方法可能抛出的异常进行说明,如果方法没有用 throws 显抛出的异常就不能写 其中:
    • @param @ return 和 @ exeption 这三个标记都是只用于方法的。
    • @param 的格式要求:@param 形参名 形参类型 形参说明
    • @return 的格式要求:@return 返回值类型 返回值说明
    • @exception 的格式要求:@exception 异常类型 异常说明
    • @ param 和 @exception 可以并列多个。

4. 自定义注解

Annotaion注解 其实也是一种引用数据类型,编译之后也是生成 xxx.class 字节码文件的。

  • 定义新的 Annotation 注解 类型使用 @interface 关键字

  • 自定义注解自动实现了 java.lang.annotation.Annotation接口

在这里插入图片描述

在这里插入图片描述

自定义注解的格式如下:

public @interface MyAnnotation {
    
}

// 
[修饰列表] @interface 注解名/(注解类名) {
    
}

使用 IDEA 创建一个 注解类型: 鼠标右键 ——> new 一个选择 :

在这里插入图片描述

如下查看该 我们该自定义的注解 MyAnnotation 的 UML 图:可以清楚的看到该 注解类型是自动继承了该 java.lang.annotation.Annotation 接口的

在这里插入图片描述

但是事实上却是自动实现了 java.lang.annotation.Annotation 接口。

在这里插入图片描述

Java 8之前,注解只能是在声明的地方所使用,Java8 开始,注解可以应用 在任何地方 。这里的任何地方包括:包,类,构造器,方法,成员变量,参数,局部变量的声明 。这些信息被保存在 注解 Annotaion 的“ name = value” 键值对中。

举例如下: 并没有出现任何的报错的情况。

在这里插入图片描述

4.1 注解中的属性

在注解中可以定义属性。

Java中的注解中的属性:看着像方法,但实际在注解当中是属性 name

格式如下:

String value();
// 数据类型 属性名();  // 看似是方法,其实在注解中是属性

注解中的属性可以是任何类型:byte, short, int, long, float, double, boolean, char, String, long, Class, 枚举类型。再或者是自定义类型。

举例:

public @interface MyAnnotation {
    
    String value();

}

注意: 如果该注解中定义了属性,则声明使用该注解时 必须 为其注解中的属性值赋上值,不然,是会报错的。

如下,我们为该 @MyAnnotation 注解定义了属性,使用时却没有赋值,报如下编译错误。

在这里插入图片描述

为注解中的属性赋值的格式如下:

@MyAnnotaion(value="Tom") // 注意:在该注解中定义的是什么类型的值,就赋值对应的值,不然会报错的
// @注解名(注解中的属性名=对应赋值的属性值)

举例:

在这里插入图片描述

如果该注解中只有一个属性值,并且该注解的属性名为 value ,则在赋值时,可以省略其 为value的属性名,直接写值

注意一定要满足两个条件:1. 该注解中只有一个属性值,2.该属性名为 value

举例:

在这里插入图片描述


为注解中的多个属性赋值格式如下: 多个属性值,使用逗号分隔开来,就可以了。

 @MyAnnotation(value = "Tom",value2 = "123")
// @注解名(注解中的属性名=值,注解中的属性名=值) :多个属性值使用逗号分隔开。

注意: 当注解中存在多个属性值时,其中所有该注解中的属性值都必须赋值,不然编译报错,如下:

在这里插入图片描述

必须将注解中的所有属性值都赋值上值才行:如下:如果注解中存在两个或两个以上的属性,就算其中存在一个属性名为 value ,其赋值时,该value 属性名是不可以省略的。必须写明所有的属性名的进行赋值。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

注解中的属性可以设置默认值,使用关键字``格式如下:

String value() default "Tom";
// 数据类型 属性名() default  默认值;  注意需要和定义的类型保证一致。

举例:

public @interface MyAnnotation {
    String value() default "Tom";

}

注解中属性设置了,默认值的是可以选择不进行赋值操作,使用定义的默认值。

举例如下:

在这里插入图片描述

4.2 注解中属性为:数组的赋值

注解中的属性值是可以定义为数组属性的格式如下:

String[] arr(); // 定义数组为属性值
数据类型[] 属性名(); 

举例:

public @interface MyAnnotation {

    String value();

    String[] arr();

}

注解中以数组为属性的赋值格式如下:

@MyAnnotation(value = "Tom",arr = {"hello","world"})
@注解名(属性名=,属性名={,})

举例:

在这里插入图片描述

当数组属性所赋值的参数只有一个时,可以省略{} 花括号。如下

在这里插入图片描述

5. JDK 内置的三个基本注解

下面我们来认识一下,JDK 中三个常见的基本注解。

5.1 @Override: 限定重写父类方法, 该注解只能用于方法

在这里插入图片描述

@Override : 的作用就是在编译期间:让编译器检查该方法是否正确的实现了 重写 操作。其中的重写的方法名是否存在错误,方法的返回值类型是否是父类中/接口中的一致。不一致编译报错,提示我们改正。

@OVerride 注解的源码,可以看到该注解是没有定义属性的。

package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

注意 : 该注解只能使用在方法上(因为该注解的源码中被@Target(ElementType.METHOD)元注解修饰了),在其他位置上是会编译报错的。如下:

在这里插入图片描述


@OVerride 注解的使用: 较少了我们编程程序时,上的简单符号上以及一些基本的语法错误。

在这里插入图片描述

5.2 @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。

在这里插入图片描述

@Deprecated : 该注解表示:表示所修饰的元素(类,方法等)已过时了,不建议使用它了。建议替换成其他的方法。

@Depecated 源码: 可以看到该注解是没有定义属性的。

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * A program element annotated &#64;Deprecated is one that programmers
 * are discouraged from using, typically because it is dangerous,
 * or because a better alternative exists.  Compilers warn when a
 * deprecated program element is used or overridden in non-deprecated code.
 *
 * @author  Neal Gafter
 * @since 1.5
 * @jls 9.6.3.6 @Deprecated
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

常见的,在我们的 java.util.lang 包下的 Date 中的 Date(String s) 构造器是被 @Deprecated 注解修饰了的。

在这里插入图片描述

在IDEA 中 如果我们调用了,被 @Deprecated 修饰的属性,方法,构造器,会给一个直观的将该属性/方法以删除线的方式显示处理并提示你建议使用别的方式替换 。如下

在这里插入图片描述

我们也可以自己写一个这样的被@Deprecated 修饰的属性/方法/类/构造器。举例如下:

在这里插入图片描述

5.3 @SuppressWarnings: 抑制编译器警告

在这里插入图片描述

@SuppressWarnings ** :指示应该在注解元素(以及包含在该注解元素中所有程序元素中的所有程序元素)中取消显示指定的编译器警告。换句话说:就是告诉编译器忽略此处代码产生的警告**。 注意是警告不是异常。

@SuppressWarnings的源码 ,可以看到该注解定义了一个名为 value 的属性。


package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * Indicates that the named compiler warnings should be suppressed in the
 * annotated element (and in all program elements contained in the annotated
 * element).  Note that the set of warnings suppressed in a given element is
 * a superset of the warnings suppressed in all containing elements.  For
 * example, if you annotate a class to suppress one warning and annotate a
 * method to suppress another, both warnings will be suppressed in the method.
 *
 * <p>As a matter of style, programmers should always use this annotation
 * on the most deeply nested element where it is effective.  If you want to
 * suppress a warning in a particular method, you should annotate that
 * method rather than its class.
 *
 * @author Josh Bloch
 * @since 1.5
 * @jls 4.8 Raw Types
 * @jls 4.12.2 Variables of Reference Type
 * @jls 5.1.9 Unchecked Conversion
 * @jls 5.5.2 Checked Casts and Unchecked Casts
 * @jls 9.6.3.5 @SuppressWarnings
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

举例: 这里我们定义一个 int num = 1 / 0 语句,IDEA 该我们提示了警告了。

在这里插入图片描述

当我们加上了 @SuppressWarnings IDEA 就没有这个警告了。如下:

在这里插入图片描述

在这里插入图片描述

具体的其他应用大家可以移步至:🔜🔜🔜
https://blog.csdn.net/qq_43842093/article/details/122386115?ops_request_misc=&request_id=&biz_id=102&utm_term=%20@SuppressWarnings%E7%9A%84%E4%BD%BF%E7%94%A8&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-122386115.142
Eclipse Galileo版本支持的抑制警告的名称:

关键字用途
allto suppress all warnings (抑制所有警告)
boxingto suppress warnings relative to boxing/unboxing operations (抑制装箱、拆箱操作时候的警告)
castto suppress warnings relative to cast operations (抑制映射相关的警告)
dep-annto suppress warnings relative to deprecated annotation (抑制启用注释的警告)
deprecationto suppress warnings relative to deprecation (抑制过期方法警告)
fallthroughto suppress warnings relative to missing breaks in switch statements (抑制确在switch中缺失breaks的警告)
finallyto suppress warnings relative to finally block that don’t return (抑制finally模块没有返回的警告)
hidingto suppress warnings relative to locals that hide variable(抑制相对于隐藏变量的局部变量的警告)
incomplete-switchto suppress warnings relative to missing entries in a switch statement (enum case)(忽略没有完整的switch语句)
nlsto suppress warnings relative to non-nls string literals( 忽略非nls格式的字符)
nullto suppress warnings relative to null analysis( 忽略对null的操作)
rawtypesto suppress warnings relative to un-specific types when using generics on class params( 使用generics时忽略没有指定相应的类型)
restrictionto suppress warnings relative to usage of discouraged or forbidden references( 抑制禁止使用劝阻或禁止引用的警告)
serialto suppress warnings relative to missing serialVersionUID field for a serializable class( 忽略在serializable类中没有声明serialVersionUID变量)
static-accessto suppress warnings relative to incorrect static access( 抑制不正确的静态访问方式警告)
synthetic-accessto suppress warnings relative to unoptimized access from inner classes( 抑制子类没有按最优方法访问内部类的警告)
uncheckedto suppress warnings relative to unchecked operations( 抑制没有进行类型检查操作的警告)
unqualified-field-accessto suppress warnings relative to field access unqualified( 抑制没有权限访问的域的警告)
unusedto suppress warnings relative to unused code( 抑制没被使用过的代码的警告)

6. 元注解

有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。Java标准库已经定义了一些元注解,我们只需要使用元注解,通常不需要自己去编写元注解。

6.1 @Target

在这里插入图片描述

@Target 源码:其中存在一个类型为 ElementType[] 枚举类型数组属性名为 value 的属性。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

ElementType的枚举源码 :

/package java.lang.annotation;
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Target : 最常用的元注解是@Target。使用@Target可以定义Annotation能够被应用于源码的哪些位置:

  • 类或接口:ElementType.TYPE
  • 字段:ElementType.FIELD
  • 方法:ElementType.METHOD
  • 构造方法:ElementType.CONSTRUCTOR
  • 方法参数:ElementType.PARAMETER

举例:

在这里插入图片描述

在这里插入图片描述

@Target元注解中的 value 属性是枚举数组类型的,可以赋值多个值:比如表示该注解可以声明在方法,变量,类中 ,举例:

在这里插入图片描述

6.2 @Retention

在这里插入图片描述

@Retention 源码 : 我们可以看到如下注解中只定义了一个RetentionPolicy 的枚举类型名为 value 的属性名的属性

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

RetentionPolicy 枚举类型的源码

package java.lang.annotation;


public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

@Retention : 另一个重要的元注解@Retention定义了Annotation的生命周期:

@Rentention 时必须为该 value 成员变量指定值

  • 仅编译期:RetentionPolicy.SOURCE 表示该注解的生命周期只在编译期间有效,在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释。
  • 仅class文件:RetentionPolicy.CLASS : 在class文件中有效(即class保留) , 当运行 Java 程序时, JVM 不会保留注解。 这是默认值
  • 运行期:RetentionPolicy.RUNTIME,注意:只有定义该属性的注解,才能被反射读取到。上面两种方式都无法被反射读取到的。

如果@Retention不存在,则该Annotation默认为CLASS。因为通常我们自定义的Annotation都是RUNTIME,所以,务必要加上@Retention(RetentionPolicy.RUNTIME)这个元注解:

举例:

在这里插入图片描述

6.3 @Documented

在这里插入图片描述

@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档。默认情况下,javadoc是不包括注解的。

  • 定义为Documented的注解必须设置Retention值为RUNTIME

@Documented 的源码 从源码看,该注解没有任何属性。


package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

6.4 @Inherited

在这里插入图片描述

@Inherited: 被它修饰的 Annotation 将具有继承性。如果某个类使用了被

@Inherited : 修饰的 Annotation, 则其子类将自动具有该注解。

  • 比如:如果把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解

  • 实际应用中,使用较少

@Inherited 源码 从源码看,该注解没有任何属性。


package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

7. 通过反射获取到注解信息

想要让反射可以读取到注解中的信息,则该反射中的元注解必须是: @Retention(RetentionPolicy.RUNTIME) 才行。

举例: 这里我们使用反射读取到 fun() 方法中的 注解中的 value 属性值:

注解

package blogs.blog10;


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)  // 生命周期在:运行期,才可以被反射读取到
public @interface MyAnnotation {
    String value() default "Tom";

}

package blogs.blog10;


import java.lang.reflect.Method;

public class AnnotationTest {

    public static void main(String[] args) {
        Method method = null;

        try {
            // 获取类加载器,类对象
            Class clazz = Class.forName("blogs.blog10.AnnotationTest"); // 全类路径名

            // 获取 fun()方法
            method = clazz.getDeclaredMethod("fun");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        // 判断该方法是否存在该注解,存在才读取该注解上的属性值
        if(method.isAnnotationPresent(MyAnnotation.class)) {
            // 获取该注解对象
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            // // 获取该注解的属性值,就像对象.属性一样
            String value = annotation.value();
            System.out.println(value);
        }

    }

    @MyAnnotation("lihua")
    public void fun() {
        int num = 0;
    }

}




在这里插入图片描述

8. 总结:

  1. 设计注解类型时,必须考虑该类型注解的基数。现在可以使用注解零次,一次,或者如果注解的类型被标记为 @Repeatable 多次。也可以通过使用 @Target 元注解来限制注解类型的使用位置。例如,您可以创建只能在方法和字段上使用的可重复注解类型。重要的是仔细设计注解类型,以确保使用注解的程序员发现它尽可能灵活和强大。
  2. 注解的作用:减少程序中的错误,提高程序员的开发效率。以及框架上的运用。
  3. 注意:注解中的属性必须赋值,不然编译无法通过,除非该属性设置了默认值信息,建议注解中的属性设置上默认值。
  4. 当注解中只有一个属性,并且该属性名为 value ,则在赋值上可以省略属性名。
  5. 注解多个值上的赋值,以及数组类型的属性值的赋值。
  6. 元注解:修饰注解上的注解,特别掌握:@Target,@Retention 这两个元注解,其中的属性值上的赋值的意义。

9. 最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善 。谢谢大家,江湖再见,后会有期 !!!

在这里插入图片描述

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

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

相关文章

【Eye】Fake News Reading on Social Media: An Eye-tracking Study

Fake News Reading on Social Media: An Eye-tracking Study Abstract 在网上传播假新闻&#xff08;以及一般的虚假信息&#xff09;最近被认为是威胁整个社会的一个主要问题。这种传播在很大程度上是由于新的媒体形式&#xff0c;即社交网络和在线媒体网站。研究人员和从业…

Python WebDriver自动化测试

Webdriver Selenium 是 ThroughtWorks 一个强大的基于浏览器的开源自动化测试工具&#xff0c;它通常用来编写 Web 应用的自动化测试。 Selenium 2&#xff0c;又名 WebDriver&#xff0c;它的主要新功能是集成了 Selenium 1.0 以及 WebDriver​&#xff08;WebDriver 曾经是…

CentOS8基础篇7:Linux系统启动配置

一、Linux系统的启动过程 Linux的启动过程大体分为五个阶段&#xff1a; 1&#xff0e;计算机主机加电后&#xff0c;CPU初始化自身&#xff0c;接着在硬件固定位置执行一条指令。这条指令跳转到BIOS&#xff0c;BIOS找到启动设备并获取MBR&#xff0c;该MBR指向LILO或GRUB。 …

steam/csgo游戏搬砖,适合个人/团队操作的创业项目(内附详细操作流程)

不懂得小伙伴继续听我娓娓道来&#xff01; 首先准备工作&#xff0c;需要用到的软件&#xff1a; 软件&#xff1a; 1、电脑&#xff08;开网页不卡的就行&#xff09; 2、ti子 3、谷歌浏览器&#xff08;多开方便些&#xff0c;别的也可以&#xff09; 4、桌面令牌 5、…

Vue的表单处理全解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录表单处理知识点基本用法文本多行文本单选按钮复选框多个复选框选择框值绑定单选按钮复选框选择框修饰符.number.trim综合小练习表单处理 在日常的开发中&#xff0c…

urllib之urlopen和urlretrieve的headers传入以及parse、urlparse、urlsplit的使用

urllib库是什么?urllib库python的一个最基本的网络请求库&#xff0c;不需要安装任何依赖库就可以导入使用。它可以模拟浏览器想目标服务器发起请求&#xff0c;并可以保存服务器返回的数据。urllib库的使用&#xff1a;1、request.urlopen(1)只能传入url的方式from http.clie…

有状态登录和无状态登录详解

有状态登录和无状态登录详解一 有状态登录二 无状态登陆无状态登陆介绍&#xff1a;无状态token生成方式一 Jwt方式二 RSA256非对称加密方式三 区别与差异四 参考连接一 有状态登录 有状态登录(Session)&#xff1a; 传统上&#xff0c;我们会使用 Session 和 Cookie 来保存用…

云计算介绍

云计算介绍概述云分类服务模式应用起源传统 IT 技术存在的问题云计算的产生云计算的发展趋势主要特点关键技术关键技术一览表虚拟化桌面显示协议用户个性化配置海量数据并行计算云安全相关技术相关技术一览表分布式计算网格计算效用计算概述 云计算&#xff08;Cloud Computin…

rest和rpc的区别

一、rest&#xff1a; REST 不是一种协议&#xff0c;它是一种架构。大部分REST的实现中使用了RPC的机制&#xff0c;大致由三部分组成&#xff1a; 1、method&#xff1a;动词&#xff08;get、post之类的&#xff09; 2、Host&#xff1a;URI&#xff08;统一资源标识&…

华为OD机试题,用 Java 解【静态扫描最优成本】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

2023-02-28 mmap的原理及使用-思考

摘要: 最近在使用mmap解决数据库内存占用损耗过高导致OOM的问题, 不得不说在有些场景下mmap是非常有用. 本文主要涉及一些对mmap的思考. mmap本身的思考: mmap和文件系统的交互规则是什么mmap中给进程虚拟内存映射的文件上的部分,是什么? 为什么是页缓存? 有没有文件缓存?…

Vscode快速配置(1)之基础工具

VScode快速配置(1)之基础工具(v1.0) Author&#xff1a;Once Day Date&#xff1a;2023年2月19日 漫漫长路&#xff0c;才刚刚开始… &#xff08;嵌入式程序员开发环境&#xff09; 1. 概述 下面是一些基础插件&#xff0c;基本上嵌入式程序员都会用到。 首先是远程连接…

力扣-销售分析III

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1084. 销售分析III二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结…

Apache Hive入门

文章目录一、Apache Hive概述1.1、什么是Hive1.2、使用Hive原因1.3、Hive和Hadoop关系二、Hive功能思想2.1、映射信息记录2.2、SQL语法解析、编译三、Hive架构、组件3.1、Hive架构图3.2Hive组件四、Hive常用操作4.1、数据类型4.1.1、基本数据类型4.1.2、集合数据类型4.2、数据库…

动态网页的核心——JSP

文章目录1&#xff0c;JSP 概述2&#xff0c;JSP 小案例2.1 搭建环境2.2 导入 JSP 依赖2.3 创建 jsp 页面2.4 编写代码2.5 测试3&#xff0c;JSP 原理4&#xff0c;JSP 总结4.1 JSP的 缺点4.2技术的发展历程4.3JSP的必要性最后说一句1&#xff0c;JSP 概述 JSP&#xff08;全称…

IB数学/生物/化学/物理所需的教材有哪些

高中阶段的学习是迈向大学的重要步骤&#xff0c;涉及到的课程分为许多结构&#xff0c;其中最为常见的则是通过IB, AP和A-Level的学习&#xff0c;实现迈入国外大学的目的。 IB课程即国际文凭组织IBO&#xff08;International Baccalaureate Organization&#xff09;&#x…

「TCG 规范解读」规范结构

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…

「TCG 规范解读」TCG 主规范-命令

可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alliance,TCPA)所开发的规范。现在的规范都不是最终稿,都…

为什么需要学习shell、shell的作用

课程基于B站于超课程笔记 03 Shebang的正确玩法_哔哩哔哩_bilibili P1 shell的作用 P2 shell执行命令的流程 P3 Shebang的正确玩法 什么是shell及组成 shell概念 shelll组成 Shebang概念 /bin/sh /bin/bash一样&#xff0c;都是指向一个bash解释器 [rootlocalhost ~]#…

JVM篇之类加载与字节码技术

一.类文件结构 首先获得.class字节码文件 方法&#xff1a; 在文本文档里写入java代码&#xff08;文件名与类名一致&#xff09;&#xff0c;将文件类型改为.javajava终端中&#xff0c;执行javac X:…\XXX.java // HelloWorld 示例 public class HelloWorld {public stat…