Java笔记(JUnit、反射、注解)

news2025/1/13 5:53:57

一、JUnit单元测试


1. JUnit的介绍


JUnit是一个Java语言的单元测试工具。有了它我们在开发阶段就可以对自己编写的功能模块进行单元测试(就是一块一块去测试),看看是否达到具体预期(这样小Bug我们自己就能解决)。

黑盒测试:不需要写代码,给定输入值,看程序是否能够输出期望的值。

白盒测试:需要写代码的。关注程序具体的执行流程。

在这里插入图片描述

JUnit通过注解识别测试方法:@Test@Before@After

  • @Test:用于修饰需要执行的测试方法。
  • @Before:修饰的方法会在测试方法之前被自动执行。
  • @After:修饰的方法会在测试方法执行之后自动被执行。

JUnit以上三种单元测试方法的注意事项:

  • 测试方法不能是静态方法。
  • 测试方法不能有返回值。
  • 测试方法不能有参数。


2. JUnit的使用


1、下载JUnit相关的jar包

junit-4.12下载地址: junit-4.12 https://mvnrepository.com/artifact/junit/junit/4.12

hamcrest-core下载地址: https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core/1.3

在这里插入图片描述


2、在模块下面创建一个lib目录,用于存放jar包

在这里插入图片描述


3、选中lib目录并鼠标右键,然后找到【Add as Library】并点击,将jar包添加到模块中。

在这里插入图片描述

在这里插入图片描述


4、创建一个测试类,编写测试方法,分别@Test、@Before、@After注解修饰。

/**
 * Junit快速入门
 * @author 白豆五
 * @version 2022/11/19 22:05
 * @since JDK8
 */
public class JUnitTest {
    // 定义静态成员变量 便于让测试方法访问
    private static List<Integer> list = new ArrayList<>();

	// 在测试方法之前执行
    @Before
    public void init() {
        list.add(111);
        list.add(222);
        list.add(13);
        list.add(25);
        list.add(16);
    }

	//测试方法
    @Test
    public void test() {
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
    }

    // 在测试方法之后执行
    @After
    public void print() {
        System.out.println(list);
    }
}

在这里插入图片描述

二、反射(Reflection)


1. 类加载器


1.1 类加载器的时机

当程序运行之后,第一次使用某个类的对象,类加载器(ClassLoader)会将该类的.class文件从磁盘加载到内存中,然后将该类的信息(如 成员变量、成员方法、构造方法)存储到 java.lang.Class对象中。

在这里插入图片描述


什么时候类加载器会将类的字节码文件加载到内存,并使用Class对象存储类的相关信息?

1、创建类的实例。

2、使用类的静态变量。

3、使用这个类的静态方法。

4、使用反射的方式创建某个类或者接口的对应Class对象。

5、初始化某个类的子类。

6、使用java命令运行某个主类(带main方法的类)。

public class TestClassLoder {

    /**
     * 类加载器的时机
     */
    @Test
    public void testClassLoder() {

        // Animal animal = new Animal(); // 1、创建类的实例
        // Animal.color="red";           // 2、使用类调用静态成员变量
        // Animal.print();               // 3、使用类调用静态方法

        /*
        try {
            // 4、通过反射加载这个类获取字节码对象
            Class clazz = Class.forName("com.baidou.p3_loder_time.Animal");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }*/

        // 5、初始化子类
        Animal dog = new Dog();

    }
}

class Animal {
    // 静态成员变量
    static String color = "blue";

    // 静态代码块在类加载的时候会被执行,而且只会执行一次
    static {
        System.out.println("执行了Animal的静态代码块");
    }

    // 静态方法
    static void print() {
        System.out.println(color);
    }
}

class Dog extends Animal {

}

1.2 类加载器的分类

Java中有三种不同的类加载器(ClassLoader)用于加载不同种类的class文件:(JDK8)

1、BootstrapClassLoader:根类加载器,也被称为引导类加载器。

  • 负责Java核心类库的加载(如 jdk1.8.0_201\jre\lib\rt.jar)

    在这里插入图片描述

  • 它是用C++编写的,是JVM自带的类加载器。

  • 该加载器无法直接获取。(如 System、String获取加载器返回的值为null)


2、ExtClassLoader:扩展类加载器。

  • ***负责加载JRE的扩展目录中的jar包。***(如 jdk1.8.0_201\jre\lib\ext)
    在这里插入图片描述

3、AppClassLoader:系统类加载器/应用类加载器。

  • Java语言编写的类加载器,用于加载我们定义的类和第三方jar包中的类

类加载器加载机制

双亲委派机制: 谁用谁加载。

当加载类的时候,首先会问委托父加载器(如AppClassLoader)它负不负责加载,如果它不会则继续向上找。但是不管是谁加载 .class文件只能被加载一次。

在这里插入图片描述
这三个类加载器之间不存在继承关系,ClassLoader是的他们的最终父类。


1.3 如何获取类加载器

用Class对象.getClassLoader()方法获取类加载器。

在这里插入图片描述
在这里插入图片描述

import org.junit.Test;
import sun.net.spi.nameservice.dns.DNSNameService;

/**
 * 获取类加载器
 * @author 白豆五
 * @version 2022/11/21 19:49
 * @since JDK8
 */
public class Demo04ClassLoder {

    /**
     * 获取根类加载器
     */
    @Test
    public void boot() {
        // String类 是核心类库rt.jar里的 由BootstrapClassLoader负则加载
        // 获取String类的Class对象
        Class<String> clazz = String.class;
        // 获取类加载器对象
        ClassLoader classLoader = clazz.getClassLoader();
        System.out.println(classLoader);// BootstrapClassLoader是根类加载器是C++编写,不让我们直接获取,所以返回值为null
    }

    /**
     * 获取扩展加载器
     */
    @Test
    public void ext() {
        // DNSNameService是扩展类  由ExtClassLoader负则加载
        // 获取DNSNameService类的Class对象
        Class<DNSNameService> clazz = DNSNameService.class;
        // 获取类加载器对象
        ClassLoader classLoader = clazz.getClassLoader();
        System.out.println(classLoader);//sun.misc.Launcher$ExtClassLoader@28a418fc
    }

    /**
     * 获取应用类加载器
     */
    @Test
    public void app() {
        // Demo04ClassLoder类是自己编写的类  由AppClassLoader负则加载
        // 获取Demo04ClassLoder类的Class对象
        Class<Demo04ClassLoder> clazz = Demo04ClassLoder.class;
        // 获取类加载器对象
        ClassLoader c1 = clazz.getClassLoader();
        System.out.println(c1);//sun.misc.Launcher$AppClassLoader@18b4aac2
        // 获取应用类加载器的委托父加载器对象(扩展类加载器)
        ClassLoader c2 = c1.getParent();
        System.out.println(c2);//sun.misc.Launcher$ExtClassLoader@28a418fc
        // 获取扩展类加载器的委托父加载器对象(根类加载器)
        ClassLoader c3 = c2.getParent();
        System.out.println(c3);//因他是c++编写不让直接获取,所以拿到的是null
    }
}

在这里插入图片描述


2. 反射的介绍


原文:https://blog.csdn.net/weixin_42298270/article/details/113371164


反射机制指的是程序在运行时能够获取自身的信息。在Java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。
要使用一个类,就要先把它加载到虚拟机中,生成一个Class对象。这个Class对象就保存了这个类的一切信息。反射机制的实现,就是获取这个Class对象,通过Class对象去访问类、对象的元数据以及运行时的数据。

反射是一种机制,利用该机制在程序运行的过程中,对类进行解剖并且去操作类的成员(成员变量,成员方法,构造方法)。要想使用反射,就必须要获取该类的字节码对象(也叫Class对象)。

反射的应用场景:如主流的开发框架(如spring-frammework、mybaits等等)、IDEA(智能化的语法提示等等)。


3. Class类的对象


Class类也是有对象的,但是程序员无法自己创建,由JVM帮助创建,程序员可以获取到该Class类型的对象,从而完成相关的操作。

3.1. 获取Class对象的三种方法

  • 方式一:Class c1 = Class.forName("类的全名称,即包名.类名");, forName是Class类的静态方法。
  • 方式二:Class c2 = 类名.class属性,每个类都默认有一个class属性。
  • 方式三:Class c3 = 对象.getClass();,getClass是Object类的方法。

pojo类:

public class User {
    private String name;
    private int age;

    //空参构造
    public User() {
    }

    //满参
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }


    //只给name赋值
    public User(String name) {
        this.name = name;
    }

    //只给age赋值
    private User(int age) {
        this.age = age;
    }

    private char[] my2CharArray(String str) {
        return str.toCharArray();
    }

    public int getSum(int a, int b) {
        return a + b;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

测试类:

/**
 * 获取Class对象
 *
 * @author 白豆五
 * @version 2022/11/21 21:49
 * @since JDK8
 */
public class Demo04GetClass {


    /**
     * 方式一:对象.getClass()获取对应的字节码对象
     */
    @Test
    public void test1(){
        User user = new User();
        Class c1 = user.getClass();
        //调用Class类的toString()方法
        System.out.println(c1); //class com.baidou.pojo.User
    }


    /**
     * 方式二:类名.class属性获取对应的字节码对象
     */
    @Test
    public void test2(){
        Class<User> c2 = User.class;
        //调用Class类的toString()方法
        System.out.println(c2); //class com.baidou.pojo.User
    }

    /**
     * 方式三:Class.forName()获取对应的字节码对象
     */
    @Test
    public void test3() throws ClassNotFoundException {
        Class<?> c3 = Class.forName("com.baidou.pojo.User");
        System.out.println(c3); //class com.baidou.pojo.User
    }


    /**
     * 基本数据类型,也有对应的Class对象
     */
    @Test
    public void test4(){
        Class<Integer> c1 = int.class;
        System.out.println(c1); //int
    }
}

3.2 Class类的常用方法

下面的成员方法都是通过与类关联的Class对象调用。

  • public String getName():获取类的全路径名,即包名+类名。
  • public String getSimpleName():获取类的类名(类名、接口名、注解名等等)。
  • public T newInstance()throws InstantiationException, IllegalAccessException:使用反射的方式创建对象,会调用该类的无参构造方法,如果该类没有无参构造方法会报 InstantiationException(实例化异常)
/**
 * Class类的常用方法
 */
@Test
public void testClassNewInstance()  {
    // 获取Animal类的字节码对象
    Class<Animal> animalClass = Animal.class;

    String name = animalClass.getName();  //获取Animal类的全路径名,包名+类名
    System.out.println(name); //com.baidou.p3_loder_time.Animal

    System.out.println(animalClass.getSimpleName()); //获取类名

    try {
        // 反射的方式创建animal对象
        Animal animal = animalClass.newInstance();
        System.out.println(animal);
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

}

在这里插入图片描述

Java源程序通过编译会生成字节码文件,字节码文件会被类加载器加载到内存方法区中,同时针对.class文件创建一个Class类型的对象(存储类的信息),然后该对象被保存到堆内存中。这个Class对象里面封装了操作构造器、成员方法、成员变量的api,这样我们通过反射可以操作.class文件中成员变量、成员方法、构造方法啦。


4. 反射获取构造方法(Constructor)


反射获取构造方法的步骤:
         1、获取类的Class对象
         2、Class对象.get构造器的方法。

4.1 获取构造方法

1、返回一个public修饰的指定参数构造方法,不传参默认调用无参构造方法。

public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException                                             

2、返回多个public修饰的构造方法。

public Constructor<?>[] getConstructors() throws SecurityException

3、返回一个任意修饰符的指定参数构造方法。

//返回一个任意修饰符的指定参数构造方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 
												throws NoSuchMethodException,SecurityException      


// 暴力反射
//java.lang.reflect.AccessibleObject类,成员方法:
public void setAccessible(boolean flag)
       // 参数:true,取消 Java 语言访问检查        private 失效
       // 参数:false,实施 Java 语言访问检查       private 有效    
// 私有构造方法对象调用setAccessible()方法,取消Java语言访问检查
constructor.setAccessible(true);

//Constructor,Field,Method类,都可以调用setAccessible方法,进行暴力反射                     

4、返回多个任意修饰符的构造方法。

public Constructor<?>[] getDeclaredConstructors() throws SecurityException

示例:

public class User {
    private String name;
    private int age;

    //空参构造
    public User() {
    }

    //满参
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }


    //只给name赋值
    public User(String name) {
        this.name = name;
    }

    //只给age赋值
    private User(int age) {
        this.age = age;
    }

    private char[] my2CharArray(String str) {
        return str.toCharArray();
    }

    public int getSum(int a, int b) {
        return a + b;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

(1) 获取public修饰的所有构造方法对象

/**
 * 获取public修饰的所有构造方法对象
 */
@Test
public void test1() throws ClassNotFoundException {
    //获取类的Class对象
    Class<?> c1 = Class.forName("com.baidou.pojo.User");
    //取public修饰的所有构造方法对象
    for (Constructor<?> cons : cons1) {
        System.out.println(cons);
    }
}

在这里插入图片描述

(2) 获取所有构造方法对象(包含private修饰的)

/**
 * 获取所有构造方法对象(包含private修饰的)
 */
@Test
public void test2() throws ClassNotFoundException {
    //获取类的Class对象
    Class<?> c2 = Class.forName("com.baidou.pojo.User");
    // 获取所有构造方法对象(包含private修饰的)
    Constructor<?>[] cons2 = c2.getDeclaredConstructors();
    for (Constructor<?> constructor : cons2) {
        System.out.println(constructor);
    }
}

在这里插入图片描述


(3) 获取public修饰的空参构造方法对象

/**
 * 获取public修饰的空参构造方法对象
 */
@Test
public void test3() throws Exception {
    //获取类的Class对象
    Class<?> c3 = Class.forName("com.baidou.pojo.User");
    //获取public修饰的空参构造方法对象
    Constructor<?> cons3 = c3.getConstructor();
    System.out.println(cons3);
}

在这里插入图片描述


(4) 获取public修饰的第一个参数是String类型,第二个参数是int类型的构造方法对象

/**
 * 获取public修饰的第一个参数是String类型,第二个参数是int类型的构造方法对象
 */
@Test
public void test4() throws Exception {
    //获取类的Class对象
    Class<?> c4 = Class.forName("com.baidou.pojo.User");
    //获取public修饰的第一个参数是String类型,第二个参数是int类型的构造方法对象
    Constructor<?> cons4 = c4.getConstructor(String.class,int.class);
    System.out.println(cons4);
}

在这里插入图片描述


(5) 获取private修饰的参数是int类型的构造方法对象

/**
 * 获取private修饰的参数是int类型的构造方法对象
 */
@Test
public void test5() throws Exception {
    //获取类的Class对象
    Class<?> c5 = Class.forName("com.baidou.pojo.User");
    //获取private修饰的参数是int类型的构造方法对象
    Constructor<?> cons5 = c5.getDeclaredConstructor(int.class);
    System.out.println(cons5);
}

在这里插入图片描述


4.2 执行构造方法创建具体对象

1、调用java.lang.reflect.Constructor类中的newInstance()方法:

// 根据方法参数传递的具体数据,调用指定的构造方法,从而创建一个具体的对象
// 可变参数 可以是0个或多个 ,Object[] 
public T newInstance(Object ... initargs)

2、快捷方式:Class对象.newInstance()方法,调用该类的无参构造方法创建对象,如果该类没有无参构造方法会报 InstantiationException(实例化异常)。

public T newInstance()throws InstantiationException, IllegalAccessException

示例:反射获取空参构造方法并运行

/**
* 反射获取空参构造方法并运行
*/
@Test
public void newInstance1() throws Exception {
   // 获取字节码对象
   Class<?> clazz = Class.forName("com.baidou.pojo.User");
   // 反射获取空参构造方法对象
   Constructor<?> con = clazz.getConstructor();
   // 执行空参构造方法对象,创建具体的实例
   User user = (User) con.newInstance();
   System.out.println(user);
}

在这里插入图片描述


示例:反射带参构造方法并运行

/**
* 反射带参构造方法并运行
*/
@Test
public void newInstance2() throws Exception {
   // 获取字节码对象
   Class<?> clazz = Class.forName("com.baidou.pojo.User");
   // 反射获取满参构造方法对象 public User(String name,int age)
   Constructor<?> con = clazz.getConstructor(String.class,int.class);
   // 执行满参构造方法对象,创建具体的实例
   User user = (User) con.newInstance("白豆五",18);
   System.out.println(user);

}

在这里插入图片描述


示例:反射创建对象的快捷方式

/**
 * 反射创建对象的快捷方式
 */
@Test
public void newInstance3() throws Exception {
    // 获取字节码对象
    Class<?> clazz = Class.forName("com.baidou.pojo.User");
    // 反射创建对象的快捷方式 class对象.newInstance()方法
    Object obj =  clazz.newInstance();
    System.out.println(obj);
}

在这里插入图片描述


示例:反射获取私有构造方法并运行

/**
* 反射获取私有构造方法并运行
*/
@Test
public void newInstance4() throws Exception {
   // 获取字节码对象
   Class<?> clazz = Class.forName("com.baidou.pojo.User");
   // 反射获取私有构造方法对象 p private User(int age)
   Constructor<?> con1 = clazz.getConstructor( int.class);
   // 执行私有构造方法对象,创建具体的实例
   User user = (User) con1.newInstance( 18);
   System.out.println(user);

}

在这里插入图片描述

解决方案:使用getDeclaredConstructor()方法获取私有方法

/**
 * 反射获取私有构造方法并运行
 */
@Test
public void newInstance4() throws Exception {
    // 获取字节码对象
    Class<?> clazz = Class.forName("com.baidou.pojo.User");
    // 反射获取私有构造方法对象 p private User(int age)
    // Constructor<?> con1 = clazz.getConstructor( int.class); //NoSuchMethodException
    Constructor<?> con2 = clazz.getDeclaredConstructor(int.class);
    // 执行私有构造方法对象,创建具体的实例
    User user = (User) con2.newInstance( 18);
    System.out.println(user);

}

在这里插入图片描述
解决方案:取消访问检查

/**
 * 反射获取私有构造方法并运行
 */
@Test
public void newInstance4() throws Exception {
    // 获取字节码对象
    Class<?> clazz = Class.forName("com.baidou.pojo.User");
    // 反射获取私有构造方法对象 p private User(int age)
    // Constructor<?> con1 = clazz.getConstructor( int.class); //NoSuchMethodException
    Constructor<?> con2 = clazz.getDeclaredConstructor(int.class);
    con2.setAccessible(true); // 取消访问检查
    // 执行私有构造方法对象,创建具体的实例
    User user = (User) con2.newInstance( 18);
    System.out.println(user);
}

在这里插入图片描述



5. 反射获取成员变量(Field)


反射第一步先得到类对象,然后从类对象中获取类的成分对象。

Class类中获取成员变量的方法如下:

  • Field[] getFields():返回所有成员变量对象的数组(只能拿public的)。

  • Field[] getDeclaredFields():返回所有成员变量对象的数组,存在就能拿到。

  • Field getField(String name):返回单个成员变量对象(只能拿public的)。

  • Field getDeclaredField(String name):返回单个成员变量对象,存在就能拿到。


Field类中取值、赋值的方法如下:

  • void set(Object obj,Object value):为Field对象赋值。
  • Object get(Object obj):获Field对象的取值。

示例:反射获取成员变量

User.java

public class User {
    private String name;
    private int age;

    //空参构造
    public User() {
    }

    //满参
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }


    //只给name赋值
    public User(String name) {
        this.name = name;
    }

    //只给age赋值
    private User(int age) {
        this.age = age;
    }

    private char[] my2CharArray(String str) {
        return str.toCharArray();
    }

    public int getSum(int a, int b) {
        return a + b;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
/**
 * 反射获取成员变量
 */
@Test
public void testFiled() throws Exception {
    // 获取Class对象
    Class<User> clazz = User.class;
    // 快捷方式创建对象
    User user = clazz.newInstance();
    // 获取私有Field对象
    Field f1 = clazz.getDeclaredField("name");
    Field f2 = clazz.getDeclaredField("age");
    f1.setAccessible(true); //取消访问检查
    f2.setAccessible(true); //取消访问检查
    f1.set(user, "张三");                  //为name属性赋值
    f2.set(user, 18);                     //为age属性赋值
    String name = (String) f1.get(user);  //取值
    int age = (int) f2.get(user);         //取值
    System.out.println(name + "::" + age);
}

在这里插入图片描述

注意:如果某成员变量是非public的,需要打开权限(暴力反射,setAccessible(true)),然后再取值、赋值。



6. 反射获取方法(Method)


也是通过Class对象拿Method对象。

Class类中获取成员方法的方法如下:

  • Method[] getMethods():返回所有成员方法对象的数组(只能拿public的)。

  • Method[] getDeclaredMethods():返回所有成员方法对象的数组,存在就能拿到。

  • Method getMethod(String name,Class<?>...parameterTypes):返回单个成员方法对象(只能拿public的)。

  • Method getDeclaredMethod(String name,Class<?>...parameterTypes):返回单个成员方法对象,存在就能拿到。


Method类中用于触发执行的方法如下:

  • Object invoke(Object obj, Object... args): 运行方法。
    • 参数一:用obj对象调用该方法。
    • 参数二:调用方法的传递的参数(如果没有就不写)。
    • 返回值:方法的返回值(如果没有就不写)。

示例1:获取setName()、getName()、toString()方法并执行。

/**
 * 获取setName()、getName()、toString()方法并执行
 * public String getName()
 * public void setName(String name)
 * public String toString()
 */
@Test
public void testgetMethoods() throws Exception {
    // 获取Class对象
    Class<User> clazz = User.class;
    // 快捷方式创建对象
    User user = clazz.newInstance();
    // 获取Method对象
    Method setName = null;
    Method getName = null;
    Method toString = null;
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
        switch (method.getName()) {

            case "setName":
                setName = method;
                break;
            case "getName":
                getName = method;
                break;
            case "toString":
                toString = method;
                break;
        }
    }

    // System.out.println(setName);
    // System.out.println(getName);
    // System.out.println(toString);

    // 执行Method对象对应的方法
    setName.invoke(user,"张三");
    Object name = getName.invoke(user);
    System.out.println(name);
    Object tostr = toString.invoke(user);
    System.out.println(tostr);
}

在这里插入图片描述



三、注解(Annotation)


1. 什么是注解?


  • 注解(Annotation): 也叫元数据。一种代码级别的说明。
  • 它是JDK5.0引入的一个新特性,与类、接口、枚举是在同一个层次。
  • 它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,标注/注释(comment)。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


2. 注解的作用


  • 编写文档:通过代码里标识的注解生成文档。(例如,生成文档javadoc文档)
  • 代码分析:通过代码里标识的注解对代码进行分析。(例如,注解的反射)
  • 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查。(例如,Override覆盖重写)

3. 常见注解


  • @author:用来标识作者名。
  • @version:用于标识对象的版本号,适用范围:文件、类、方法。
  • @Override:用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败。
  • @FunctionalInterface: 检测是否是函数式接口(JDK8新特性)。
  • @Deprecated:可以用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告(删除线 )。
  • @SuppressWarnings:取消显示指定的编译器警告。
    • @SuppressWarnings(value=“all”):抑制所有警告。
    • @SuppressWarnings(value=“deprecation”): 抑制过期方法警告。


4. 自定义注解


自定义注解就是自己做一个注解来玩玩。

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口。

自定义注解的格式:

public @interface 注解名 {
    属性集
    // public 属性类型 属性名() default 默认值;            
}


// 空注解: 没有任何属性 	
/*
有属性集的注解: 
    属性的定义格式一:数据类型 属性名(); 没有默认值的属性
                
    属性的定义格式二:数据类型 属性名() default 默认值; 有默认值的属性型对应的一维数组
*/	
//注解属性可以选择的数据类型:8种基本类型,String类型,枚举类型,注解类型,Class类型以及以上任意类
// 空注解
public @interface MyTest {
    //没有任何属性 
}

//定义有属性集的注解
public @interface MyTest2  {
    String name();//String 类型的属性 name,没有默认值
    int age() default 18;//int 类型的属性 age,默认值 18
    String[] hobbies();//String 类型的数组 hobbies
    MyAnno01 myAnno01();//注解类型
}

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

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

相关文章

敏感词检测库ToolGood.Words中 WordsHelper类使用简介

C#开源敏感词检测库ToolGood.Words中的类WordsHelper为文本辅助操作类&#xff0c;支持繁体简体互换、全角半角互换、数字转成中文大写、拼音操作等功能&#xff0c;本文对照参考文献1&#xff0c;对该类的用法进行简要介绍。   WordsHelper类中主要的辅助函数如下表所示&…

基于SVM的航空发动机故障诊断系统设计

目录 第1关&#xff1a;准备实验数据 任务描述&#xff1a; 相关知识&#xff1a; 一、获取数据&#xff1a; 二、读取数据集&#xff1a; 三、如何找出对应的数据列&#xff1a; 编程要求&#xff1a; 测试说明&#xff1a; 第二关&#xff1a;数据预处理 任务描述&…

python习题002--字符串处理

目录 一&#xff0c;题目展示&#xff1a; 二&#xff0c;题目解答 a&#xff09;判断两个字符串是否相等 b)忽略大小写判断两个字符串是否相等 c,d)判断字符串是否以指定的字符串开始或者是结尾 e&#xff09; 获取字符串的长度 f&#xff09; 字符串切片&#xff0c…

认定省级专精特新的条件

之前报省级专精特新的一个条件是先认定市级专精特新&#xff0c;但是打算2023年申报省级专精特新的企业就不需要先申请市级的专精特新了&#xff0c;那是可以直接申请省级专精特新吗&#xff1f;并不是&#xff01; 接下来打算申请2023年省级专精特新的企业需要先认定山东省创…

18.5.4 分布式恢复

文章目录18.5.4 分布式恢复18.5.4.1 分布式恢复的连接18.5.4.1.1 为分布式恢复端点选择地址18.5.4.1.2 分布式恢复的压缩18.5.4.1.3 用于分布式恢复的复制用户18.5.4.1.4 分布式恢复的 SSL 和身份验证18.5.4.2 分布式恢复的克隆18.5.4.2.1 克隆的先决条件18.5.4.2.2 克隆的阈值…

VsCode配置Kotlin运行环境

目录 需求 前置条件 步骤 问题 一 二 结果 需求 设备上有一个 Android Studio 但是太大了, 于是就想着用 VS Code 配置一个轻量级的,而且 VS Code里面好多插件我用着也比较舒服. 前置条件 Java JDK1.8 或者 11 别的版本没试过 有基于Android Studio 的 Kotlinc的环…

c++ - 第12节 - 模板进阶

1.非类型模板参数 模板参数分为类型形参与非类型形参类型形参&#xff08;可以认为是虚拟类型&#xff09;&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。非类型形参&#xff08;可以认为是常量&#xff09;&#xff1a;用一个常量作…

带命名空间的arxml读取

一、前言 读取带命名空间的arxml,最好的方式是创建一个字典来存放你自己的前缀并在搜索函数中使用它们: 二、解读如下ns.xml文件: <?xml version"1.0" encoding"UTF-8"?> <AUTOSAR xmlns"http://autosar.org/schema/r4.0" xmlns:xsi…

365天深度学习训练营-第7周:咖啡豆识别

目录 一、前言 二、我的环境 三、代码实现 四、VGG-16框架 五、LeNet5模型 六、模型改进 一、前言 >- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/xLjALoOD8HPZcH563En8bQ) 中的学习记录博客** >- **&#x1f366; 参考…

基于STM32G431嵌入式学习笔记——四、LED+KEY+LCD综合练习(基于第12届蓝桥杯显示部分题目)

在学习了前三节LED、LCD、KEY基本操作后&#xff0c;我们就已经成功掌握蓝桥杯必考的三大样内容了&#xff0c;本节以第12届蓝桥杯显示部分内容进行综合练习&#xff1a; 一、真题引入 1.功能概述 2.LCD显示界面 &#xff08;1&#xff09;车位显示界面 &#xff08;2&#…

PostgreSQL数据库缓冲区管理器——本地缓冲区管理

本地缓冲区管理器(local buffer manager)为temporary表&#xff08;无需WAL-logged或checkpointed&#xff09;进行快速缓冲区管理&#xff0c;API定义在src/backend/storage/buffer/localbuf.c中。 获取LocalBuffer 初始化 首先解释temp_buffers GUC参数&#xff0c;其用于…

Servlet学习日志

Hello Web Web World Wide Web 全球广域网->也称为万维网 是一种基于超文本和HTTP协议的分布式应用架构 HTML&#xff08;HyperText Mark-up Language&#xff09;:用于链接网络上的信息 HTTP协议&#xff08;HyperText Transfer Protocol&#xff09;:规定了服务端与客户…

国际海运流程有哪些,国际海运物流哪家比较好

国际海运的优点是运输费划算&#xff0c;并且可以走的货物类目多&#xff0c;合适大物件、大批的长距离运送。进出境运输工具的负责人、进出境物品的所有人或者他们的代理人向海关办理货物、物品或运输工具进出境手续及相关海关事务的过程&#xff0c;包括向海关申报、交验单据…

分析 SpringBoot 底层机制【Tomcat 启动分析 +Spring 容器初始化 +Tomcat 如何关联 Spring 容器 】

目录 一.搭建 SpringBoot 底层机制开发环境 1.pom.xml文件配置 2.springboot主程序MainApp.java 3.启动项目&#xff0c;然后我们准备开始思考 4.开始思考 底层机制分析: 仍然是 我们实现 Spring 容器那一套机制 IO/文件扫描注解反射 集合映射集合映射 二.源码分析: Spri…

DeepLab V2学习笔记

DeepLab V2遇到的相关问题以及解决方法对于DeepLab V1的优化模型总结补充的一个小知识点ASPPLearning rate policy实验结果消融实验实验结果遇到的相关问题以及解决方法 和DeepLab V1中遇到的问题几乎没有什么太大的差别&#xff0c;在文章的引言部分作者提出了在语义分割中遇…

小程序商城拓展中小商户“线上时间”,系统化思维

在数字经济时代初期&#xff0c;新一代信息基础设施建设仍有待完善&#xff0c;在拓展“互联网”应用场景中应不断缩小“数字鸿沟”&#xff0c;逐渐向产业和行业下沉&#xff0c;让互联网巨头和中小微商户共享数字技术的红利&#xff0c;也因此将推动包括传统商户在内的数字化…

政务系统信息网络安全的风险评估

在当今信息时代的大形势下&#xff0c;互联网从普及到飞速发展&#xff0c;政务系统信息网络安全的问题也日益被重视起来。一方面&#xff0c;人们应该了解到政务系统信息网络安全的重要性&#xff1b;另一方面&#xff0c;人们对政务系统信息网络安全风险评估工作有所了解。有…

公厕智能感应皂液盒,无液手机信息提醒

传统式的洗手液一按一压。有时候经常控制不住量&#xff0c;一不小心就容易按多&#xff0c;弄得洗手台乱七八糟&#xff0c;满身也是黏哒哒的&#xff0c;特别让人糟心。刚做完饭&#xff0c;满手油腻&#xff0c;或是刚上完厕所&#xff0c;去按洗手液泵势必会弄脏它。 所以智…

【Python+Appium】开展自动化测试(一)

目录 前言 一&#xff0c;安装JDK&#xff0c;配置JDK环境变量 1&#xff0c;下载jdk 2&#xff0c;安装jdk 3&#xff0c;配置jdk环境变量 二&#xff0c;安装Android SDK&#xff0c;配置Android SDK环境 1&#xff0c;下载Android SDK 2&#xff0c;双击SDK Manager…

【日常记录】解决‘GLIBC_2.34‘ not found,并且gcc制定glibc版本编译

小荣的日常记录 &#x1f525;系列专栏&#xff1a;日常记录 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月21日&#x1f334; &#x1f36d;作者水平很有限&#xff0c;如果发现错…