1.JavaWebJava基础加强[万字长文]-Junit、反射、注解核心知识点梳理

导语:

一、Junit单元测试

1.Junit测试概述

2.Junit使用步骤

3.Junit_@Before&@After

二、反射

1.反射概述

2.反射获取字节码Class对象的三种方式

3.Class对象功能概述

4.Class对象功能_获取Field

5.Class对象功能_获取Constructor

6.Class对象功能_获取Method

7.反射案例

三、注解

1.注解概念

2.JDK内置注解

3.自定义注解_格式&本质

4.自定义注解_属性定义

5.自定义注解_元注解

6.解析注解

7.注解案例_简单的测试框架

结语:


导语:

    这篇文档详细介绍了Java编程中Junit测试、反射原理和注解应用的核心知识点,旨在帮助初学者掌握Java基础,也可作为进阶学习的参考资料。

一、Junit单元测试

1.Junit测试概述

  • 黑盒测试:无需编写代码,只需给输入值,检查输出是否符合预期。

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

案例代码:
    展示了如何使用JUnit进行黑盒测试和白盒测试:


public class Calculator {public int add(int a, int b) {return a + b;}public int subtract(int a, int b) {return a - b;}
}

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;public class CalculatorTest {private Calculator calculator;@Beforepublic void setUp() {calculator = new Calculator();}// 黑盒测试@Testpublic void testAdd() {int result = calculator.add(1, 2);assertEquals(3, result);}// 白盒测试@Testpublic void testSubtract() {int result = calculator.subtract(5, 3);assertEquals(2, result);}
}

2.Junit使用步骤

  • 定义测试类(以Test结尾)

  • 定义测试方法(以test开头)

  • 给测试方法添加@Test注解

  • 导入Junit依赖

案例代码:


import org.junit.Assert;
import org.junit.Test;public class CalculatorTest {@Testpublic void testAdd() {Calculator c = new Calculator();int result = c.add(1, 2);Assert.assertEquals(3, result);}@Testpublic void testSubtract() {Calculator c = new Calculator();int result = c.subtract(5, 3);Assert.assertEquals(2, result);}
}

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>

3.Junit_@Before&@After

  • @Before:初始化方法,在测试方法执行前自动执行

  • @After:释放资源方法,在测试方法执行后自动执行

代码案例:


import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class CalculatorTest {private Calculator calculator;@Beforepublic void setUp() {// 初始化操作calculator = new Calculator();System.out.println("setUp...");}@Afterpublic void tearDown() {// 释放资源calculator = null;System.out.println("tearDown...");}@Testpublic void testAdd() {int result = calculator.add(1, 2);Assert.assertEquals(3, result);}@Testpublic void testSubtract() {int result = calculator.subtract(5, 3);Assert.assertEquals(2, result);}
}

二、反射

1.反射概述

  • 将类的各个组成部分封装为其他对象

  • 好处:在运行时操作对象,提高程序扩展性

代码案例:


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;public class ReflectionExample {public static void main(String[] args) {try {// 获取类的Class对象Class<?> personClass = Class.forName("Person");// 获取所有public字段Field[] fields = personClass.getFields();for (Field field : fields) {System.out.println("Public field: " + field);}// 获取所有public方法Method[] methods = personClass.getMethods();for (Method method : methods) {System.out.println("Public method: " + method);}// 获取所有public构造器Constructor<?>[] constructors = personClass.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println("Public constructor: " + constructor);}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

2.反射获取字节码Class对象的三种方式

  • Class.forName()

  • 类名.class

  • 对象.getClass()

代码案例:

public class ReflectionExample {public static void main(String[] args) {// 方式1:使用Class.forName()try {Class<?> personClass1 = Class.forName("Person");System.out.println(personClass1);} catch (ClassNotFoundException e) {e.printStackTrace();}// 方式2:使用类名.classClass<?> personClass2 = Person.class;System.out.println(personClass2);// 方式3:使用对象.getClass()Person person = new Person();Class<?> personClass3 = person.getClass();System.out.println(personClass3);}
}

3.Class对象功能概述

  • 获取成员变量

  • 获取构造方法

  • 获取成员方法

  • 获取全类名

案例代码:

public class ReflectionExample {public static void main(String[] args) {try {// 获取Person类的Class对象Class<?> personClass = Class.forName("Person");// 获取所有成员变量Field[] fields = personClass.getDeclaredFields();for (Field field : fields) {System.out.println("Field: " + field);}// 获取所有构造方法Constructor<?>[] constructors = personClass.getDeclaredConstructors();for (Constructor<?> constructor : constructors) {System.out.println("Constructor: " + constructor);}// 获取所有成员方法Method[] methods = personClass.getDeclaredMethods();for (Method method : methods) {System.out.println("Method: " + method);}// 获取全类名String className = personClass.getName();System.out.println("Full class name: " + className);} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

4.Class对象功能_获取Field

  • Field[] getFields()

  • Field getField(String name)

  • Field[] getDeclaredFields()

  • Field getDeclaredField(String name)

案例代码:

public class ReflectionExample {public static void main(String[] args) {try {// 获取Person类的Class对象Class<?> personClass = Class.forName("Person");// 获取所有public字段Field[] publicFields = personClass.getFields();for (Field field : publicFields) {System.out.println("Public Field: " + field);}// 获取指定名称的public字段Field publicField = personClass.getField("name");System.out.println("Specific Public Field: " + publicField);// 获取所有字段(包括private)Field[] allFields = personClass.getDeclaredFields();for (Field field : allFields) {System.out.println("Field: " + field);}// 获取指定名称的字段(包括private)Field privateField = personClass.getDeclaredField("age");System.out.println("Specific Field: " + privateField);} catch (ClassNotFoundException | NoSuchFieldException e) {e.printStackTrace();}}
}

5.Class对象功能_获取Constructor

  • Constructor[] getConstructors()

  • Constructor getConstructor(参数类型…)

  • Constructor getDeclaredConstructor(参数类型…)

  • Constructor[] getDeclaredConstructors()

案例代码:

public class ReflectionExample {public static void main(String[] args) {try {// 获取Person类的Class对象Class<?> personClass = Class.forName("Person");// 获取所有public构造器Constructor<?>[] publicConstructors = personClass.getConstructors();for (Constructor<?> constructor : publicConstructors) {System.out.println("Public Constructor: " + constructor);}// 获取指定参数的public构造器Constructor<?> publicConstructor = personClass.getConstructor(String.class);System.out.println("Specific Public Constructor: " + publicConstructor);// 获取所有构造器(包括private)Constructor<?>[] allConstructors = personClass.getDeclaredConstructors();for (Constructor<?> constructor : allConstructors) {System.out.println("Constructor: " + constructor);}// 获取指定参数的构造器(包括private)Constructor<?> privateConstructor = personClass.getDeclaredConstructor(String.class, int.class);System.out.println("Specific Constructor: " + privateConstructor);} catch (ClassNotFoundException | NoSuchMethodException e) {e.printStackTrace();}}
}

6.Class对象功能_获取Method

  • Method[] getMethods()

  • Method getMethod(String name, 参数类型…)

  • Method[] getDeclaredMethods()

  • Method getDeclaredMethod(String name, 参数类型…)

案例代码:

public class ReflectionExample {public static void main(String[] args) {try {// 获取Person类的Class对象Class<?> personClass = Class.forName("Person");// 获取所有public方法Method[] publicMethods = personClass.getMethods();for (Method method : publicMethods) {System.out.println("Public Method: " + method);}// 获取指定名称和参数的public方法Method publicMethod = personClass.getMethod("setName", String.class);System.out.println("Specific Public Method: " + publicMethod);// 获取所有方法(包括private)Method[] allMethods = personClass.getDeclaredMethods();for (Method method : allMethods) {System.out.println("Method: " + method);}// 获取指定名称和参数的方法(包括private)Method privateMethod = personClass.getDeclaredMethod("showAge");System.out.println("Specific Method: " + privateMethod);} catch (ClassNotFoundException | NoSuchMethodException e) {e.printStackTrace();}}
}

7.反射案例

  • 从配置文件读取类名和方法名

  • 使用反射加载类、创建对象、执行方法

案例代码:

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;public class ReflectionExample {public static void main(String[] args) {try {// 加载配置文件Properties properties = new Properties();InputStream inputStream = ReflectionExample.class.getClassLoader().getResourceAsStream("config.properties");properties.load(inputStream);// 读取配置文件中的类名和方法名String className = properties.getProperty("class.name");String methodName = properties.getProperty("method.name");// 使用反射加载类Class<?> classObj = Class.forName(className);// 使用反射创建对象Object obj = classObj.newInstance();// 使用反射执行方法Method method = classObj.getMethod(methodName);method.invoke(obj);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

三、注解

1.注解概念

  • 说明程序,给计算机看的

  • 分类:文档、代码分析、编译检查

案例代码

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 文档注解
@Deprecated
public class AnnotationExample {// 编译检查注解@Overridepublic String toString() {return "This is a overridden toString method";}// 代码分析注解@SuppressWarnings("unchecked")public void analyzeCode() {// 这里会有类型转换的警告Object obj = new Object();String str = (String) obj;}// 自定义注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation {String value() default "";}@MyAnnotation("Hello")public void annotatedMethod() {System.out.println("Annotated method");}
}

2.JDK内置注解

  • @Override

  • @Deprecated

  • @SuppressWarnings

案例代码:


public class AnnotationExample {// 使用@Override注解标记重写父类方法@Overridepublic String toString() {return "This is a overridden toString method";}// 使用@Deprecated注解标记已过时的方法@Deprecatedpublic void oldMethod() {System.out.println("This is an old method");}// 使用@SuppressWarnings注解压制编译器警告@SuppressWarnings("unchecked")public void analyzeCode() {// 这里会有类型转换的警告Object obj = new Object();String str = (String) obj;}
}

3.自定义注解_格式&本质

  • 本质是接口,默认继承Annotation接口

案例代码:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义一个自定义注解
@Target(ElementType.METHOD) // 注解的作用目标
@Retention(RetentionPolicy.RUNTIME) // 注解的保留策略
public @interface MyAnnotation {// 定义一个value属性String value();
}// 使用自定义注解
public class AnnotationExample {// 在方法上使用自定义注解,并指定value属性值@MyAnnotation(value = "Hello")public void annotatedMethod() {System.out.println("Annotated method");}
}

4.自定义注解_属性定义

  • 返回值类型:基本数据类型、String、枚举、注解、数组

  • 属性赋值

案例代码:


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义一个自定义注解
@Target(ElementType.METHOD) // 注解的作用目标
@Retention(RetentionPolicy.RUNTIME) // 注解的保留策略
public @interface MyAnnotation {// 定义一个String类型的value属性,并指定默认值为"Hello"String value() default "Hello";// 定义一个int类型的age属性int age();// 定义一个枚举类型的gender属性Gender gender();// 定义一个注解类型的anno属性MyAnnotation2 anno();// 定义一个String数组类型的tags属性String[] tags();
}// 定义一个枚举类型
enum Gender {MALE, FEMALE
}// 定义一个自定义注解
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {String value();
}// 使用自定义注解
public class AnnotationExample {// 在方法上使用自定义注解,并为所有属性赋值@MyAnnotation(value = "World", age = 30, gender = Gender.MALE, anno = @MyAnnotation2("anno2"), tags = {"tag1", "tag2"})public void annotatedMethod() {System.out.println("Annotated method");}
}

5.自定义注解_元注解

  • @Target

  • @Retention

  • @Documented

  • @Inherited

案例代码:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义一个自定义注解
@Target(ElementType.METHOD) // 指定该注解只能用于方法
@Retention(RetentionPolicy.RUNTIME) // 指定注解保留到运行时
@Documented // 指定该注解会被包含在javadoc中
@Inherited // 指定该注解可以被继承
public @interface MyAnnotation {// 定义一个String类型的value属性,并指定默认值为"Hello"String value() default "Hello";
}// 使用自定义注解
public class AnnotationExample {// 在方法上使用自定义注解@MyAnnotation("World")public void annotatedMethod() {System.out.println("Annotated method");}
}// 继承了父类的注解
public class ChildClass extends AnnotationExample {// 子类会继承父类的@MyAnnotation注解@Overridepublic void annotatedMethod() {System.out.println("Child class");}
}

6.解析注解

  • 获取注解定义位置的对象

  • 获取指定的注解

  • 调用注解方法获取属性值

案例代码:


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义一个自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {// 定义一个String类型的value属性String value();
}// 使用自定义注解
public class AnnotationExample {// 在方法上使用自定义注解,并指定value属性值@MyAnnotation(value = "Hello")public void annotatedMethod() {System.out.println("Annotated method");}
}// 解析注解
public class AnnotationParser {public static void main(String[] args) throws Exception {// 获取方法对象Method method = AnnotationExample.class.getMethod("annotatedMethod");// 获取方法上的MyAnnotation注解MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);// 调用注解方法获取value属性值String value = myAnnotation.value();// 输出value属性值System.out.println("Value: " + value);}
}

7.注解案例_简单的测试框架

  • 自定义注解

  • 定义测试类

  • 执行测试

案例代码:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;// 定义一个自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {// 定义一个String类型的value属性String value();
}// 定义一个测试类
public class TestClass {// 定义一个测试方法,并使用自定义的Test注解@Test(value = "测试 add 方法")public void testAdd() {int result = 1 + 2;assertEquals(3, result);}@Test(value = "测试 subtract 方法")public void testSubtract() {int result = 5 - 3;assertEquals(2, result);}// 定义一个断言方法public static void assertEquals(int expected, int actual) {if (expected != actual) {throw new RuntimeException("测试失败:期望值=" + expected + " 实际值=" + actual);}}
}// 执行测试
public class TestRunner {public static void main(String[] args) {Class<?> testClass = TestClass.class;try {// 获取测试类对象Object testInstance = testClass.newInstance();// 遍历测试类中的所有方法for (Method method : testClass.getMethods()) {// 检查方法是否使用了Test注解if (method.isAnnotationPresent(Test.class)) {try {// 执行测试方法method.invoke(testInstance);System.out.println("测试成功:" + method.getAnnotation(Test.class).value());} catch (Exception e) {System.out.println("测试失败:" + method.getAnnotation(Test.class).value());}}}} catch (Exception e) {e.printStackTrace();}}
}

结语:

    以上内容涵盖了JUnit单元测试、反射机制、注解的概念及自定义,以及如何解析注解并应用在简单的测试框架案例中。这些知识点对于Java后端开发中的框架设计、代码规范以及测试都非常重要。通过这些知识点的学习,可以加深对Java高级特性的理解,并为后续框架学习和项目开发打下基础。

#JavaWeb

欢迎大家交流,金三银四求职季期间关注公众号送面试宝典。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

响应人大代表王旭的提议:996程序员也要每天一节体育课

哈喽&#xff0c;我是熊子峰&#xff0c;38岁程序员&#xff0c;正在结合AI写作进行自我成长&#xff0c;穿越程序员的中年危机&#xff0c;这是第 69 篇日更文章。 每天一节体育课 今天&#xff0c;看到一条新闻&#xff0c;人大代表王旭提议中小学生每天应该有一节体育课&am…

你不得不知道的Python AI库

Python是人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;领域中使用最广泛的编程语言之一&#xff0c;拥有丰富的库支持各种AI和ML任务。本文介绍一些经典的Python AI库。 1. NumPy 简介&#xff1a;NumPy&#xff08;Numerical Python&#xff09;…

Docker部署ruoyi前后端分离项目

目录 一. 介绍前后端项目 二. 搭建局域网 2.1 创建网络 2.2 注意点 三. Redis 3.1 安装 3.2 配置redis.conf文件 3.3 测试 四. 安装MySQL 4.1 安装 4.2 配置my2.cnf文件 4.3 充许远程连接 五. 若依部署后端服务 5.1 数据导入 5.2 使用Dockerfile自定义镜像 5.3 运行…

基于单片机的医院输液系统设计

目 录 摘 要 Ⅰ Abstract Ⅱ 引 言 1 1系统方案设计与论证 3 1.1系统硬件结构总体设计方案 3 1.2点滴速度测量电路方案的选择与论证 3 1.3液面检测电路方案的选择与论证 4 1.4通过电机控制滴速电路的方案与论证 4 1.5显示器接口电路方案选择与论证 5 1.6键盘接口电路方案选择与…

土地利用数据分类过程教学/土地利用分类/遥感解译/土地利用获取来源介绍/地理数据获取

本篇主要介绍如何对影像数据进行分类解译&#xff0c;及过程教学&#xff0c;示例数据下载链接&#xff1a;数据下载链接 一、背景介绍 土地是人类赖以生存与发展的重要资源和物质保障&#xff0c;在“人口&#xff0d;资源&#xff0d;环境&#xff0d;发展&#x…

稀碎从零算法笔记Day6-LeetCode:长度最小的子数组

前言&#xff1a;做JD的网安笔试题&#xff0c;结果查找子串&#xff08;单词&#xff09;这个操作不会。痛定思痛&#xff0c;决定学习滑动数组 题型&#xff1a;数组、双指针、滑动窗口 链接&#xff1a;209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 来…

关于yolov8的DFL模块(pytorch以及tensorrt)

先看代码 class DFL(nn.Module):"""Integral module of Distribution Focal Loss (DFL).Proposed in Generalized Focal Loss https://ieeexplore.ieee.org/document/9792391"""def __init__(self, c116):"""Initialize a convo…

使用 SPL 高效实现 Flink SLS Connector 下推

作者&#xff1a;潘伟龙&#xff08;豁朗&#xff09; 背景 日志服务 SLS 是云原生观测与分析平台&#xff0c;为 Log、Metric、Trace 等数据提供大规模、低成本、实时的平台化服务&#xff0c;基于日志服务的便捷的数据接入能力&#xff0c;可以将系统日志、业务日志等接入 …

DevExpress报表-->更换数据库连接

今天遇到了一个问题&#xff0c;因公司更换IP地址&#xff0c;原先连接报表数据库的IP地址也因此更改。但是&#xff0c;我不知道如何直接修改连接报表的数据。为了解决这个问题&#xff0c;我决定给大家演示一下具体的操作步骤。 换句话说: 将DevExpress报表直接从一个电脑的…

Unity UGUI之InputField(TMP)基本了解

Unity的InputField组件是用于在Unity中创建可供用户输入文本的输入框的UI组件。通过InputField组件&#xff0c;可以让用户在运行时输入文本&#xff0c;比如用户名、密码、搜索关键字等。其中TMP版本的InputField是基于TextMeshPro的InputField组件&#xff0c;提供了更多的文…

李国庆喊话雷军建议小米汽车降在20万内

尊敬的雷军先生&#xff1a; 近日&#xff0c;小米汽车的问世引起了业界内外的广泛关注&#xff0c;作为一位企业家和消费者&#xff0c;我对此深感振奋。然而&#xff0c;在欣喜之余&#xff0c;我也想向您提出一个建议&#xff1a;将小米汽车的价格定位在20万以内。 首先&am…

第三讲 汇编初步 课程随手记

一、寄存器 32位CPU通用寄存器如下图所示&#xff1a; 因为教材依照的是32位CPU寄存器&#xff0c;而我安装的是64位寄存器&#xff0c;所以找了一下64位的寄存器的资料 PS&#xff1a;一般来说&#xff0c;Intel处理器字节存储顺序为小端法存储&#xff0c;是指数据的高字节保…