java入坑之注解

news2024/11/24 13:21:13

一、注解入门 

注解:Annotation

  • 从JDK 1.5 引入
  • 位于源码中(代码/注释/注解),使用其他工具进行处理的标签
  • 注解用来修饰程序的元素,但不会对被修饰的对象有直接的影响
  • 只有通过某种配套的工具才会对注解信息进行访问和处理

主要用途

  • 提供信息给编译器/IDE工具
  • 可用于其他工具来产生额外的代码/配置文件等
  • 有一些注解可在程序运行时访问,增加程序的动态性

 1.1常见普通注解

1.2常见元注解

 1.3自定义注解

二、Java预定义的普通注解

Java预定义的普通注解是一些用于修饰类、方法、字段等元素的注解,它们可以提供一些编译器或运行时的信息,例如检查重写方法是否正确、标记过时的元素、忽略警告信息等。Java预定义的普通注解有以下几种:

  • @Override:用于修饰方法,表示该方法重写了父类或接口中的方法,如果没有匹配的父类或接口方法,编译器会报错。
  • @Deprecated:用于修饰类、方法、字段等元素,表示该元素已经过时,不建议使用,如果使用该元素,编译器会发出警告。
  • @SuppressWarnings:用于修饰类、方法、字段等元素,表示忽略指定的编译器警告,可以指定一个或多个警告类型。
  • @SafeVarargs:用于修饰可变参数的方法或构造器,表示该方法或构造器不会对泛型参数进行不安全的操作,可以忽略堆污染警告。
  • @FunctionalInterface:用于修饰函数式接口,表示该接口只有一个抽象方法,可以用lambda表达式实现。

 2.1@Override

@Override注解是一种用于表示方法重写的注解,它可以让编译器检查子类的方法是否正确地覆盖了父类或接口中的方法,如果没有匹配的父类或接口方法,编译器会报错。@Override注解可以提高代码的可读性和可维护性,也可以避免一些潜在的错误。

在子类中重写父类的方法,使用@Override注解标明

class Animal {
    public void eat() {
        System.out.println("Animal eats");
    }
}

class Dog extends Animal {
    @Override // 表示重写父类的eat方法
    public void eat() {
        System.out.println("Dog eats");
    }
}

 在实现接口的类中重写接口的方法,使用@Override注解标明

interface Shape {
    public void draw();
}

class Circle implements Shape {
    @Override // 表示重写接口的draw方法
    public void draw() {
        System.out.println("Draw a circle");
    }
}

2.2@Deprecated

@Deprecated注解是一种用于标记已经过时的类、方法、字段等元素的注解,它可以让编译器在使用该元素时发出警告,提醒开发者不要再使用该元素,而是使用新的替代方案

package org.example;

class Animal {
    @Deprecated
    public void makeSound() {
        System.out.println("This method is deprecated.");
    }

    public void communicate() {
        System.out.println("Animals communicate in various ways.");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal();

        // 使用已过时的方法,会生成警告
        animal.makeSound();

        // 使用新方法
        animal.communicate();
    }
}

2.3@SuppressWarnings

@SuppressWarnings注解是一种用于忽略指定的编译器警告的注解,它可以用于修饰类、方法、字段等元素,可以指定一个或多个警告类型。

  1. 压制各种不同类型的警告信息,使得编译器不显示警告
  2. 各种不同类型是叠加,如修饰类的警告类型,和修饰方法的警告类型,对于方法来说,是叠加的。
  3. 警告类型名称是编译器/IDE工具自己定的,Java规范没有强制要求哪些名称。编译器厂商需要自行协商,保证同名警告类型在各个编译器.上一样工作。

package org.example;

import java.util.ArrayList;
import java.util.List;

public class SuppressWarningsExample {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        // 创建一个泛型列表,不指定泛型类型
        List myList = new ArrayList();
        myList.add("Item 1");
        myList.add("Item 2");

        // 使用 @SuppressWarnings 抑制未经检查的警告
        List<String> stringList = myList;

        // 不会再生成未经检查的警告
        System.out.println(stringList.get(0));
        System.out.println(stringList.get(1));
    }
}

 2.4@SafeVarargs

@SafeVarargs是一个用于抑制编译器警告的注解,它可以用于修饰使用可变参数(varargs)的方法或构造器,表示该方法或构造器不会对其可变参数执行潜在的不安全的操作,例如将其转换为不同的类型或返回给外部。@SafeVarargs注解可以提高代码的可读性和可维护性,也可以避免一些潜在的错误。

@SafeVarargs注解在Java 7中引入,最初只能用于修饰final或static的方法或构造器,因为这些方法或构造器不能被重写,从而保证了安全性。但是在Java 9中,@SafeVarargs注解也可以用于修饰private的实例方法,因为这些方法也不能被重写。

2.5@FunctionalInterface

@FunctionalInterface是一个用于标记函数式接口的注解,它表示该接口只有一个抽象方法,可以用lambda表达式或方法引用来实现。函数式接口是Java 8引入的一种新特性,它可以让代码更简洁、清晰和优雅。函数式接口的一些例子有Runnable、ActionListener、Comparable等。@FunctionalInterface注解可以让编译器检查接口是否符合函数式接口的定义,如果不符合,编译器会报错。@FunctionalInterface注解也可以提高代码的可读性,明确表达接口的用途。 

package org.example;



@FunctionalInterface // 表示这是一个函数式接口
interface Adder {
    int add(int a, int b); // 定义一个抽象方法add
}

public class Test {
    public static void main(String[] args) {
        Adder adder = (a, b) -> a + b; // 使用lambda表达式创建Adder接口的实例
        System.out.println(adder.add(10, 20)); // 调用add方法,输出30
    }
}

三、自定义注解

 3.1注解可以包括的类型

 3.2使用步骤

自定义注解的基本流程是:第一步,定义注解,使用@interface语法,并指定元注解(Annotation的注解)来配置注解的作用域和策略;第二步,使用注解,把注解标记在需要用到的程序代码中;第三步,解析注解,在编译期或运行时检测到注解,并进行特殊操作

 3.3特殊

  • 注解可以使用元注解来指定其作用域和策略,例如@Target指定注解可以用在哪些元素上,@Retention指定注解在什么时候有效,@Documented指定注解是否包含在用户文档中,@Inherited指定注解是否可以被子类继承,@Repeatable指定注解是否可以在同一个元素上重复使用,例如:
@Target(ElementType.METHOD) // 表示该注解只能用于方法上
@Retention(RetentionPolicy.RUNTIME) // 表示该注解在运行时有效
@Documented // 表示该注解会被javadoc工具记录
@Inherited // 表示该注解可以被子类继承
@Repeatable(MyAnnotations.class) // 表示该注解可以重复使用,需要指定一个容器注解来存放重复的注解
public @interface MyAnnotation {
    // 注解内容
}

 3.4相关代码

注解代码

package org.example;

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
//表示该注解会保留在class文件中
@Target(ElementType.METHOD)
//表示该注解只能用于方法
public @interface MultipleTest {
    int a() default 0;
    int b() default 0;
}

测试代码

package org.example;

public class Foo {
    @MultipleTest(a=1,b=1)
    public static void m1(int a, int b) {
        if (a + b < 0) {
            throw new RuntimeException("Crash");
        }
    }

    @MultipleTest
    public static void m2(int a, int b) {
        //全部采用默认值
        if (a + b < 0) {
            throw new RuntimeException("Broken");
        }
    }
    @MultipleTest(b=-2,a=1)
    public static void m3(int a, int b) {
        //全部采用默认值
        if (a + b < 0) {
            throw new RuntimeException("Broken");
        }
    }
}

解析代码

package org.example;

import java.lang.reflect.Method;

public class tes {
    public static void main(String[] args) throws Exception {
        int passed = 0, failed = 0; // 给passed变量赋值为0
        String className = "org.example.Foo";
        for (Method m : Class.forName(className).getMethods()) {
            if (m.isAnnotationPresent(MultipleTest.class)) {
                System.out.println(m.getName());
                MultipleTest st = m.getAnnotation(MultipleTest.class);
                try {
                    m.invoke(null,st.a(),st.b());
                    passed++;
                } catch (Throwable ex) {
                    System.out.printf("Test %s failed: %s %n", m, ex.getCause()); // 使用%符号代替$符号
                    failed++;
                }
            }
        }
        System.out.printf("passed:%d , failed:%d",passed,failed);
    }
}

四、 Java预定义的元注解

元注解是一种用于给其他注解进行说明的注解,它可以用来指定注解的作用域、保留策略、文档化、继承性和重复性等特性

4.1@retention 

@Retention是一个用于指定注解的保留策略的元注解,它表示注解在什么时候有效,例如源码、字节码或运行时。它需要一个RetentionPolicy类型的参数,只能是一个

@Retention的参数有以下三种取值:

  1. RetentionPolicy.SOURCE:表示注解只在源码中有效,编译器会丢弃它,不会写入字节码文件。
  2. RetentionPolicy.CLASS:表示注解在源码和字节码中都有效,编译器会把它写入字节码文件,但是虚拟机不会读取它,这是默认值
  3. RetentionPolicy.RUNTIME:表示注解在源码、字节码和运行时都有效,编译器会把它写入字节码文件,并且虚拟机会读取它,可以通过反射机制获取它
package org.example;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME) // 指定注解在运行时保留
public @interface AnimalInfo {
    String species() default "Unknown"; // 动物的种类属性,默认值为"Unknown"
    int age() default 0; // 动物的年龄属性,默认值为0
}
package org.example;

@AnimalInfo(species = "Generic Animal", age = 1) // 使用注解为这个动物类提供信息
public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnimalInfoExample {
    public static void main(String[] args) {
        // 获取Animal类的Class对象
        Class<Animal> animalClass = Animal.class;

        // 获取Animal类上的所有注解
        Annotation[] annotations = animalClass.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof AnimalInfo) {
                AnimalInfo animalInfo = (AnimalInfo) annotation;
                String species = animalInfo.species();
                int age = animalInfo.age();
                System.out.println("Species: " + species);
                System.out.println("Age: " + age);
            }
        }
    }
}

4.2 @Target

@Target是一个用于指定注解可以用在哪些元素上的元注解,它表示注解的作用范围,例如类、方法、字段、参数等。它需要一个ElementType类型的参数,可以是一个或多个

@Target的参数有以下几种取值:

  • ElementType.TYPE:表示注解可以用于类、接口、枚举或注解类型。
  • ElementType.FIELD:表示注解可以用于字段或枚举常量。
  • ElementType.METHOD:表示注解可以用于方法。
  • ElementType.PARAMETER:表示注解可以用于方法参数。
  • ElementType.CONSTRUCTOR:表示注解可以用于构造器。
  • ElementType.LOCAL_VARIABLE:表示注解可以用于局部变量。
  • ElementType.ANNOTATION_TYPE:表示注解可以用于注解类型。
  • ElementType.PACKAGE:表示注解可以用于包声明。
  • ElementType.TYPE_PARAMETER:表示注解可以用于类型参数,这是Java 8新增的特性。
  • ElementType.TYPE_USE:表示注解可以用于任何类型的使用,这也是Java 8新增的特性
import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD}) // 指定注解可以应用于类和方法
@Retention(RetentionPolicy.RUNTIME) // 指定注解在运行时保留
public @interface AnimalInfo {
    String species() default "Unknown"; // 动物的种类属性,默认值为"Unknown"
    int age() default 0; // 动物的年龄属性,默认值为0
}

4.3@Inherited

@Inherited是一个用于指明父类注解会被子类继承得到的元注解,它表示该注解可以被子类继承。它没有参数。

@Inherited的作用是让自定义的注解具有继承性,即如果一个类使用了某个注解,那么它的子类也会自动拥有该注解,而不需要再次标注。这样可以简化代码,避免重复的注解。@Inherited只对类注解有效,对于方法和属性注解无效

import java.lang.annotation.*;

@Inherited // 指示该注解可以被继承
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CustomAnnotation {
    String value() default "Default Value";
}
@CustomAnnotation(value = "Annotated Parent Class")
public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
public class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }
}
import java.lang.annotation.Annotation;

public class InheritedAnnotationExample {
    public static void main(String[] args) {
        // 获取 Cat 类的 Class 对象
        Class<Cat> catClass = Cat.class;

        // 获取 Cat 类上的所有注解,包括继承的注解
        Annotation[] annotations = catClass.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof CustomAnnotation) {
                CustomAnnotation customAnnotation = (CustomAnnotation) annotation;
                String value = customAnnotation.value();
                System.out.println("Annotation Value: " + value);
            }
        }
    }
}

4.4@Documented

@Documented是一个用于将注解包含在javadoc中的元注解,它表示该注解会被javadoc工具记录。它没有参数。

@Documented的作用是让自定义的注解在生成文档时能够显示出来,而不是被忽略。这样可以提高代码的可读性和可维护性,也可以让其他人更容易理解注解的含义和用法。@Documented只对类注解有效,对于方法和属性注解无效

import java.lang.annotation.*;

@Documented // 指示编译工具生成文档时包括此注解信息
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AnimalInfo {
    String species() default "Unknown"; // 动物的种类属性,默认值为"Unknown"
    int age() default 0; // 动物的年龄属性,默认值为0
}

4.5@Repeatable

@Repeatable是一个用于表示注解可以在同一个元素上重复使用的元注解,它需要指定一个容器注解来存放重复的注解。@Repeatable注解可以让代码更简洁和清晰,也可以避免一些潜在的错误。@Repeatable注解在Java 8中引入,最初只能用于修饰final或static的方法或构造器,但是在Java 9中,@Repeatable注解也可以用于修饰private的实例方法

package org.example;

import java.lang.annotation.*;

// 自定义注解 @RepeatableAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(RepeatableAnnotations.class) // 指示该注解可以多次应用于同一目标元素,RepeatableAnnotations.class 是容器注解
public @interface RepeatableAnnotation {
    int a() default 0;

    int b() default 0;

    int c() default 0;
}
package org.example;

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

// 容器注解 @RepeatableAnnotations
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RepeatableAnnotations {
    RepeatableAnnotation[] value(); // 一个数组属性,用于存储多个 @RepeatableAnnotation 注解
}
package org.example;

import java.lang.annotation.*;

// 示例类 Student
public class Student {
    // 使用 @RepeatableAnnotation 注解并检查条件
    @RepeatableAnnotation(a = 2, b = 3, c = 5) // 第一个 @RepeatableAnnotation 注解
    @RepeatableAnnotation(a = 4, b = 8, c = 11) // 第二个 @RepeatableAnnotation 注解
    public static void add(int a, int b, int c) {
        if (c != a + b) {
            throw new ArithmeticException("Wrong");
        }
        System.out.println("Sum: " + c);
    }

    public static void main(String[] args) throws Exception {
        String className = "org.example.Student";
        for (java.lang.reflect.Method m : Class.forName(className).getMethods()) {
            if (m.isAnnotationPresent(RepeatableAnnotations.class)) {
                RepeatableAnnotation[] annos = m.getAnnotationsByType(RepeatableAnnotation.class);
                for (RepeatableAnnotation anno : annos) {
                    System.out.println("a: " + anno.a() + ", b: " + anno.b() + ", c: " + anno.c());
                    try {
                        m.invoke(null, anno.a(), anno.b(), anno.c());
                    } catch (Throwable ex) {
                        System.out.printf("Test %s failed: %s%n", m, ex.getCause().getMessage());
                    }
                }
            }
        }
    }
}

五、注解的解析 

解的解析是指通过反射机制获取程序元素上的注解信息,并根据注解的属性值进行相应的处理。

Java注解的解析

  • RetentionPolicy.RUNTIME注解采用反射进行解析
  • RetentionPolicy.CLASS注解采用专用的字节码工具进行解析
  • RetentionPolicy.SOURCE注解采用注解处理器进行解析

注解处理器继承AbstractProcessor,重写process方法
javac  -processor  Processor1, Processor2, …   sourceJavaFile

 六、RUNTIME注解的实现本质

6.1步骤

为了获取和处理RUNTIME注解,我们需要以下几个步骤:

  1. 首先,我们需要使用Class类的forName方法或者对象的getClass方法来获取目标元素所属的Class对象。
  2. 然后,我们需要使用Class对象的getMethods、getFields、getConstructors等方法来获取目标元素所对应的Method、Field、Constructor等对象。
  3. 接着,我们需要使用Method、Field、Constructor等对象的isAnnotationPresent方法来判断目标元素上是否存在指定的RUNTIME注解。
  4. 最后,我们需要使用Method、Field、Constructor等对象的getAnnotation方法或者getAnnotationsByType方法来获取目标元素上的RUNTIME注解实例,并读取注解的属性值,然后进行相应的处理。

6.2增加代理类导出设置

RUNTIME注解代理类导出设置的具体方法有以下几种:

  • 在程序中使用System.setProperty方法来设置系统属性,例如:
System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); // 设置保存代理类
  • 在命令行中使用-D参数来设置系统属性,例如:
java -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true Main // 设置保存代理类

如果RUNTIME注解被JVM加载进来,Java可以用反射获取到注解内容

  1. 程序自动为注解产生一个代理类,来拦截注解的方法访问
  2. 代理类有一个AnnotationInvocationHandler成员变量,其内部存放所有的注解的赋值

 七、 注解的应用

7.1Servlet配置

7.2Junit

 7.3Spring&&Spring Boot

7.4Lombok 

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

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

相关文章

【职场篇】五年游戏开发老兵,我为什么劝你学UE?

我是水曜日鸡&#xff0c;一个在游戏行业摸爬滚打了5年的行业老兵。在Unity和UE4各有两年半的开发经验。曾参与开发了索尼中国之星计划之一的 《硬核机甲》 项目&#xff0c;用的是Unity引擎。目前在上海某大厂参与研发 开放世界项目&#xff0c;用的是UE4引擎。今天我就来终结…

《重构改善代码设计》

文章目录 1.重构的原则2.代码的坏味道3.第一组重构3.1.提炼函数3.2.内联函数3.3.提炼变量3.4.内联变量3.5.修改函数名称3.6.封装变量3.7.变量改名3.8.引入参数对象3.9.函数组合成类3.10.函数组合成变换3.11.拆分阶段 4. 封装4.1. 封装记录4.2. 封装集合4.3. 以对象取代基本类型…

使用cpolar配合Plex搭建私人媒体站

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频&#xff0c;已经算是生活中稀松平常的场景了&#xff0c;特别是各…

如何开启Win10虚拟机Hyper-V功能

操作步骤: 使用前提&#xff1a; 1、确保系统是 Windows 10 专业版/企业版/教育版&#xff0c;且必须是64位操作系统才支持。 提示&#xff1a;Win10家庭版不支持hyper-v。 2、使用Hyper-V需要cpu支持虚拟化并处于开启状态。 3、硬件要求及如何验证硬件兼容性&#xff1a; 硬件…

Hive 使用达梦DM8 无法识别 “COMMENT” 问题

将达梦数据库驱动 DmJdbcDriver18-8.1.2.192.jar 导入到 hive 的 lib 文件夹下 修改 hive 配置文件&#xff0c;增加 dm 数据库相关信息 <property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:dm://127.0.0.1:5236?SCHEMAhive</val…

vmware官网下载(VMware workstation 下载与安装)

Oracle RAC 安装配置part1 注册VMware 个人帐号 浏览器打开官方网站 下面是主页&#xff0c;单击Customer connter 单击立即注册 填入相关信息注册完成 需要到您邮件里的激活一下帐号 注册完成 下载VMware Workstation 单击转到CUSTOMER CONNECT (您也可以在主页login…

修饰符的笔记

修饰符 完整的教程参考下面的链接 菜鸟教程-修饰符 下面是我总结的比较精简的内容 常见的修饰符有权限修饰符和非权限修饰符 权限修饰符 权限修饰符就是我们所熟知的 private&#xff0c;public&#xff0c;protect&#xff0c;default&#xff08;什么都不写&#xff0c;默…

华为云云耀云服务器L实例评测|基于华为云云耀云服务器L实例搭建EMQX大规模分布式 MQTT 消息服务器场景体验

文章目录 前言一、&#x1f604;华为云云耀服务器二、&#x1f604;产品实例创建相关1、&#x1f9e8;开通华为云云耀服务器2、&#x1f9e8;创建华为云云耀服务器实例3、&#x1f9e8;终端登录4、&#x1f9e8;华为云云耀云服务器密码重置 三、&#x1f604;安装开源产品EMQX四…

python diffusers StableDiffusionXLPipeline 离线使用

下载sd_xl_base_1.0.safetensors https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main 我这下载后放到项目 models 里 model_path "./models/v1-5-pruned-emaonly.safetensors" # model_path "./models/v1-5-pruned.safetensors" # model…

人工智能创业,2023爆火风口项目:实景无人直播帮实体店精准获客

软件图片素材来自于公众号&#xff1a;生财风暴 关注进行领取价值1000元的采集软件&#xff0c;和呆头鹅批量剪辑和矩阵管理系统演示 把AI和直播结合在一起的实景自动直播你知道吗&#xff1f;如果提起人工智能创业项目啊&#xff0c;你还只知道CHHGPP的话&#xff0c;那不妨把…

光伏浪涌保护器综合应用工程方案

光伏浪涌保护器是一种用于保护光伏发电系统中的设备和线路免受雷电或其他瞬态过电压的影响的装置。光伏发电系统由于其分布式、室外、大面积等特点&#xff0c;容易受到雷电直击或感应&#xff0c;导致系统内部产生高能量的浪涌电流和电压&#xff0c;从而损坏光伏组件、逆变器…

竞赛选题 基于大数据的时间序列股价预测分析与可视化 - lstm

文章目录 1 前言2 时间序列的由来2.1 四种模型的名称&#xff1a; 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &…

【Git】Git 快照 Snapshot

Git 快照 Snapshot 在对 Git 基础的学习过程中&#xff0c;我们了解了 Git 仓库的基本结构&#xff1a; 工作目录暂存区版本库&#xff0c;即 .git 仓库 下面我们就通过一次修改、暂存以及提交的工作流程&#xff0c;来理解快照&#xff08;Snapshot&#xff09;的概念。 现…

基于Docker的JMeter分布式压测实战讲解

一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试。如本网站所示&#xff0c;一个JMeter实例将能够控制许多其他的远程JMeter实例&#xff0c;并对你的应用程序产生更大的负载。JMeter使用Java RMI[远程方法调用]来与分布式网络中的对象进行交互。JMeter主站…

Linux:基础开发工具之Makefile和缓冲区的基本概念

文章目录 动静态库自动化构建代码缓冲区 动静态库 首先要知道什么是链接&#xff1a; C程序中&#xff0c;并没有定义printf的函数实现,且在预编译中包含的stdio.h中也只有该函数的声明,而没有定义函数的实现 系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没…

旋转偏心裁切刀切向跟踪及半径补偿

1 裁刀半径补偿问题的提出 偏心裁刀一般皮革和纸箱行业用的比较多&#xff0c;它适用于裁切比较厚的材料。对于如图1所示的偏心裁刀&#xff0c;它的刀尖和旋转轴(也就是刀心)存在一个距离&#xff0c;设为半径r。由于改刀刀刃有方向&#xff0c;所以用该刀去切割直线时&#…

使用nvm管理node.js

使用nvm管理node.js 一、简介 nvm是一个node的版本管理工具。可以在多种系统上管理Node.js 版本的工具。使用 NVM&#xff0c;可以轻松地切换不同版本的Node.js&#xff0c;并方便地管理不同版本的全局包和本地包。 二、安装与下载 1.删除原有node.js 首先需要卸载已安装的…

免费音乐下载网站分享(MP3文件格式)

免费音乐下载网站分享&#xff08;MP3文件格式&#xff09; 最近需要下载一些歌曲&#xff0c;发现很多音乐app上下载文件都需要vip&#xff0c;再上网查询了一番&#xff0c;最后发现了一个宝藏网站&#xff0c;可以免费下载各种格式的MP3文件&#xff0c;在这里给大家分享一…

建设数字孪生智慧城市是未来城市的重要增长点

中国国家创新与发展战略研究会学术委员会常务副主席、重庆市原市长黄奇帆在《瞭望》撰文指出&#xff1a; AI时代的城市是由实体空间和数字空间组成的数字孪生城市&#xff0c;要充分重视对数字空间的治理。随着城市数字化进程的加快&#xff0c;城市、企业、个人开始形成多样化…

软件需求怎么写?

前言&#xff1a;一般来说&#xff0c;软件产品的需求人员的主要输出物就是软件需求&#xff0c;如果这个软件产品就XX系统&#xff0c;人们口中的“系统需求”和“软件需求”就没有什么区别了。在车企行业&#xff0c;推行这ASPICE体系&#xff0c;在这个体系中明确申请了系统…