• JavaSE进阶21天---第二十一天---JavaSE(​单元测试(Junit)、注解(自定义注解、元注解)、XML、DTD约束、Schema约束)


     ✨✨个人主页:沫洺的主页

    📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 

                               📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏

                               📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏     

    💖💖如果文章对你有所帮助请留下三连✨✨

    🍁单元测试

    什么是单元测试

    • 单元测试就是测试部分代码,对代码中的问题快速定位,及时修复

    Junit概述

    • Junit是一个Java编程语言的单元测试工具,是一个非常重要的测试工具

    Junit特点

    • JUnit是一个开放源代码的测试工具。

    • 提供注解来识别测试方法。

    • JUnit测试可以让你编写代码更快,并能提高质量。

    • JUnit优雅简洁。没那么复杂,花费时间较少。

    • JUnit在一个条中显示进度。如果运行良好则是绿色;如果运行失败,则变成红色。

    使用步骤

    1. 将junit的jar包导入到工程中 junit-4.9.jar

    2. 编写测试方法该测试方法必须是公共的无参数无返回值的非静态方法

    3. 在测试方法上使用@Test注解标注该方法是一个测试方法

    4. 选中测试方法右键通过junit运行该方法

    网盘

    链接:https://pan.baidu.com/s/1NgM50O0X71Qm6LncPyReiw?pwd=wznb 
    提取码:wznb 

    将jar包放进去

     代码示例

    1. package cn.moming2;
    2. import org.junit.Test;
    3. public class JunitDemo {
    4. public static void main(String[] args) {
    5. }
    6. //在要测试的代码上写上注解
    7. //被测试的方法必须是是公共的无参数无返回值的非静态方法
    8. @Test
    9. public void add(){
    10. int a = 2;
    11. int b = 3;
    12. System.out.println(a+b);
    13. System.out.println(2/0);
    14. }
    15. }

     两种运行方式

     相关注解说明

    @Before,@After其实就是赋值@Test的,所有这两个没有办法独立运行

    注解含义
    @Test表示测试该方法
    @Before在测试的方法前运行
    @After在测试的方法后运行

     代码示例

    1. package cn.moming2;
    2. import org.junit.After;
    3. import org.junit.Before;
    4. import org.junit.Test;
    5. public class JunitDemo {
    6. public static void main(String[] args) {
    7. }
    8. @Before
    9. public void before() {
    10. // 在执行测试代码之前执行,一般用于初始化操作
    11. System.out.println("before");
    12. }
    13. @Test
    14. public void test() {
    15. // 要执行的测试代码
    16. System.out.println("test");
    17. }
    18. @After
    19. public void after() {
    20. // 在执行测试代码之后执行,一般用于释放资源
    21. System.out.println("after");
    22. }
    23. }
    1. before
    2. test
    3. after

    🌿注解 

    概述

    • 对程序进行标注和解释

    注解和注释的区别

    • 注释: 给程序员看的一种标记
    • 注解: 给编译器看的标记
    • 注释不会影响代码运行,注解会影响代码运行;

    使用注解进行配置配置的优势

    • 代码更加简洁,方便

    JDK自带注解

    注解名说明
    @Override描述子类重写父类的方法
    @Deprecated描述方法过时(代码上有一道横线)
    @SuppressWarnings压制警告(灰色的代码或有波浪线的代码)

    代码示例

    父类

    1. package cn.moming2;
    2. public class Fu {
    3. public void show(){
    4. System.out.println("父类");
    5. }
    6. }

    子类

    1. package cn.moming2;
    2. @SuppressWarnings(value = "all") //压制本类中所有的警告
    3. public class Zi extends Fu{
    4. @Override //告诉编译器这是重写的方法
    5. public void show() {
    6. super.show();
    7. }
    8. @Deprecated //表示一个过时的方法
    9. public void method(){
    10. System.out.println("过时的方法");
    11. }
    12. @SuppressWarnings(value = "all") //压制本方法中所有的警告
    13. public void function1(){
    14. int a = 10;
    15. }
    16. public void function2(){
    17. int a = 10;
    18. int b = 20;
    19. }
    20. public static void main(String[] args) {
    21. Zi zi = new Zi();
    22. zi.method();
    23. }
    24. }

    🍂自定义注解

    格式

    1. public @interface 注解名称 {
    2. public 属性类型 属性名() default 默认值 ;
    3. }

    属性类型

    • 基本数据类型

    • String

    • Class

    • 注解

    • 枚举

    • 以上类型的一维数组

    代码示例

    创建注解

    注解类

    1. package cn.moming2;
    2. public @interface Anno {
    3. }

    枚举类

    1. package cn.moming2;
    2. public enum Season {
    3. SPRING,SUMMER,AUTUMN,WINTER;
    4. }

    自定义注解类

    1. package cn.moming2;
    2. public @interface AnnoDemo {
    3. //public可以省略,默认就是公共的
    4. //定义一个基本数据类型的属性
    5. public int a() default 23;
    6. //定义一个String类型的属性
    7. public String name();
    8. //定义一个Class类型的属性
    9. public Class clazz() default Anno.class;
    10. //定义一个注解类型的属性
    11. public Anno anno() default @Anno;
    12. //定义一个枚举类型的属性
    13. public Season season() default Season.SPRING;
    14. //以上类型的一维数组
    15. //int数组
    16. public int[] arr() default {1,2,3,4,5};
    17. //枚举数组
    18. public Season[] seasons() default {Season.SPRING,Season.SUMMER,Season.AUTUMN,Season.WINTER};
    19. }

    测试类

    1. package cn.moming2;
    2. //在使用注解的时候如果注解里面的属性没有指定默认值
    3. //那么我们就需要手动给出注解属性的设置值
    4. @AnnoDemo(name = "moming")
    5. public class Test {
    6. }

    注解中特殊的属性value

    特殊属性:value,如果一个注解类中,仅有一个value属性需要我们使用者赋值的时候,那么可以省略属性名直接写属性值!

    自定义注解案例

    需求

    • 自定义一个注解@Test,用于指定类的方法上,如果某一个类的方法上使用了该注解,就执行该方法

    实现步骤

    • 自定义一个注解Test,并在类中的某几个方法上加上注解
    • 在测试类中,获取注解所在的类的Class对象
    • 获取类中所有的方法对象
    • 遍历每一个方法对象,判断是否有对应的注解

    代码实现(注意没有使用junit的jar包)

    注解类

    1. package cn.momin01;
    2. import java.lang.annotation.Retention;
    3. import java.lang.annotation.RetentionPolicy;
    4. //元注解
    5. //表示Test这个注解的存活时间
    6. @Retention(value = RetentionPolicy.RUNTIME)
    7. public @interface Test {
    8. }

    使用注解类

    1. package cn.momin01;
    2. public class UseTest {
    3. //没有使用Test注解
    4. public void show(){
    5. System.out.println("UseTest....show....");
    6. }
    7. //使用Test注解
    8. @Test
    9. public void method(){
    10. System.out.println("UseTest....method....");
    11. }
    12. //使用Test注解
    13. @Test
    14. public void function(){
    15. System.out.println("UseTest....function....");
    16. }
    17. }

    反射测试类

    1. package cn.momin01;
    2. import java.lang.reflect.InvocationTargetException;
    3. import java.lang.reflect.Method;
    4. public class AnnoDemo {
    5. public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
    6. //1.通过反射获取UseTest类的字节码文件对象
    7. Class clazz = Class.forName("cn.momin01.UseTest");
    8. //创建UseTest对象,用来调用里面的方法的
    9. Object useTest = clazz.newInstance();
    10. //2.通过反射获取这个类里面所有的方法对象
    11. Method[] declaredMethods = clazz.getDeclaredMethods();
    12. //3.遍历数组得到每一个方法对象
    13. for (Method method : declaredMethods) {
    14. //4.判断方法是否有@Test注解
    15. //isAnnotationPresent(Class annotationClass)
    16. //参数:注解的字节码文件对象
    17. //返回值:布尔结果,true存在,false不存在
    18. boolean b = method.isAnnotationPresent(Test.class);
    19. //如果存在注解,就调用此方法
    20. if(b){
    21. method.invoke(useTest);
    22. }
    23. }
    24. }
    25. }
    1. UseTest....method....
    2. UseTest....function....

    🌾元注解

    概述

    • 元注解就是描述注解的注解(注解注解的注解)

    元注解介绍

    元注解名说明
    @Target指定了注解能在哪里使用
    @Retention可以理解为保留时间(生命周期)
    @Inherited表示修饰的自定义注解可以被子类继承
    @Documented表示该自定义注解,会出现在API文档里面。

    代码示例

    自定义注解(使用元注解)

    1. package cn.moming2;
    2. import java.lang.annotation.*;
    3. //指定注解使用的位置:成员变量,类,方法
    4. @Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})
    5. @Retention(RetentionPolicy.RUNTIME)//指定该注解的存货时间,不加是在源码阶段存活(.java文件),加上是在运行阶段(.class文件)
    6. @Inherited //指定该注解可以被继承
    7. public @interface Anno {//自定义注解
    8. }

    父类(使用自定义注解)

    1. package cn.moming2;
    2. @Anno
    3. public class Fu {
    4. }

    子类(继承父类)

    1. package cn.moming2;
    2. public class Zi extends Fu{
    3. }

    测试类(子类是否继承父类的注解)

    1. package cn.moming2;
    2. public class ZiDemo {
    3. public static void main(String[] args) throws ClassNotFoundException {
    4. //获取子类的字节码文件对象
    5. Class clazz = Class.forName("cn.moming2.Zi");
    6. //获取注解,判断子类是否继承父类的注解
    7. boolean result = clazz.isAnnotationPresent(Anno.class);
    8. System.out.println(result);//true表示继承了注解
    9. }
    10. }
    true

    🍃XML

    概述

    • XML的全称为(EXtensible Markup Language),是一种可扩展的标记语言
    • 可扩展:标签的名字是可以自定义的
    • 标记:标签(元素),分为自闭合标签和带开头和结尾的标签
    • 语言:通过标签来描述数据的一种编程语言

    作用

    • 用于进行存储数据和传输数据
    • 作为软件的配置文件(可读性好,可维护性高 )

    标签的语法格式

    • 标签由一对尖括号和合法标识符组成
    • 标签必须成对出现,前边的是开始标签,后边的是结束标签
    • 特殊的标签(自闭合标签)可以不成对,但是必须有结束标记
    • 标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来
    • 标签需要正确的嵌套
    • 正确的: 张三
    • 错误的: 张三
    • 元素体(标签体):开始标签和结束标签中间夹的部分

    XML语法规则

    • XML文件的后缀名为:xml
    • 文档声明必须是第一行第一列
    • version:该属性是必须存在的
    • encoding:该属性不是必须的,表示打开当前xml文件的时候应该是使用什么字符编码表(一般取值都是UTF-8)
    • standalone: 该属性不是必须的,描述XML文件是否依赖其他的xml文件,取值为yes/no
    • 必须存在一个根标签,有且只能有一个
    • XML文件中可以定义注释信息
    • XML文件中可以存在以下特殊字符
    • XML文件中可以存在CDATA区

    代码示例

    1. "1.0" encoding="UTF-8" ?>
    2. <students>
    3. <student id="1">
    4. <name>张三name>
    5. <age>23age>
    6. <info><学生信息>info>
    7. <message>]]>message>
    8. student>
    9. <student id="2">
    10. <name>李四name>
    11. <age>24age>
    12. student>
    13. students>

     可以看到和HTML很像,注意特殊字符出来的效果

    🌳xml解析

    概述

    • xml解析就是从xml中获取到数据

    常见的解析思想

    • DOM(Document Object Model)文档对象模型:就是把文档的各个组成部分看做成对应的对象。 会把xml文件全部加载到内存,在内存中形成一个树形结构,再获取对应的值

     常见的解析工具

    • JAXP: SUN公司提供的一套XML的解析的API

    • JDOM: 开源组织提供了一套XML的解析的API-jdom

    • DOM4J: 开源组织提供了一套XML的解析的API-dom4j,全称:Dom For Java

    • pull: 主要应用在Android手机端解析XML

    解析的准备工作

    网站:dom4j 去下载dom4j

    网盘

     链接:https://pan.baidu.com/s/1NgM50O0X71Qm6LncPyReiw?pwd=wznb 
    提取码:wznb

    • 将提供好的dom4j-1.6.1.zip解压,找到里面的dom4j-1.6.1.jar
    • 在idea中当前模块下新建一个libs文件夹,将jar包复制到文件夹中
    • 选中jar包 -> 右键 -> 选择add as library即可

    需求

    • 解析提供好的xml文件
    • 将解析到的数据封装到学生对象中
    • 并将学生对象存储到ArrayList集合中
    • 遍历集合

    代码实现

    学生类

    1. package cn.moming3;
    2. public class Student {
    3. private String id;
    4. private String name;
    5. private int age;
    6. public Student() {
    7. }
    8. public Student(String id, String name, int age) {
    9. this.id = id;
    10. this.name = name;
    11. this.age = age;
    12. }
    13. public String getId() {
    14. return id;
    15. }
    16. public void setId(String id) {
    17. this.id = id;
    18. }
    19. public String getName() {
    20. return name;
    21. }
    22. public void setName(String name) {
    23. this.name = name;
    24. }
    25. public int getAge() {
    26. return age;
    27. }
    28. public void setAge(int age) {
    29. this.age = age;
    30. }
    31. @Override
    32. public String toString() {
    33. return "Student{" +
    34. "id='" + id + '\'' +
    35. ", name='" + name + '\'' +
    36. ", age=" + age +
    37. '}';
    38. }
    39. }

    解析类

    1. package cn.moming3;
    2. import org.dom4j.Attribute;
    3. import org.dom4j.Document;
    4. import org.dom4j.DocumentException;
    5. import org.dom4j.Element;
    6. import org.dom4j.io.SAXReader;
    7. import java.io.File;
    8. import java.util.ArrayList;
    9. import java.util.List;
    10. /**
    11. * 利用dome4j解析xml文件
    12. */
    13. public class XmlParse {
    14. public static void main(String[] args) throws DocumentException {
    15. //1.获取一个解析器对象
    16. SAXReader saxReader = new SAXReader();
    17. //2.利用解析器把xml文件加载到内存中,并返回一个文档对象
    18. Document document = saxReader.read(new File("D:\\Teaching\\Java\\WorkSpace\\javase01\\mondule07\\xml\\student.xml"));
    19. //3.获取到根标签
    20. Element rootElement = document.getRootElement();
    21. //4.通过根标签来获取student标签
    22. //elements():可以获取调用者所有的子标签.会把这些子标签放到一个集合中返回.
    23. //elements("标签名"):可以获取调用者所有的指定的子标签,会把这些子标签放到一个集合中并返回
    24. //List list = rootElement.elements();
    25. List studentElements = rootElement.elements("student");
    26. //System.out.println(list.size());
    27. //用来装学生对象
    28. ArrayList list = new ArrayList<>();
    29. //5.遍历集合,得到每一个student标签
    30. for (Element element : studentElements) {
    31. //element依次表示每一个student标签
    32. //获取id这个属性
    33. Attribute attribute = element.attribute("id");
    34. //获取id的属性值
    35. String id = attribute.getValue();
    36. //获取name标签
    37. //element("标签名"):获取调用者指定的子标签
    38. Element nameElement = element.element("name");
    39. //获取这个标签的标签体内容
    40. String name = nameElement.getText();
    41. //获取age标签
    42. Element ageElement = element.element("age");
    43. //获取age标签的标签体内容
    44. String age = ageElement.getText();
    45. //System.out.println(id);
    46. //System.out.println(name);
    47. //System.out.println(age);
    48. Student s = new Student(id, name, Integer.parseInt(age));
    49. list.add(s);
    50. }
    51. //遍历操作
    52. for (Student student : list) {
    53. System.out.println(student);
    54. }
    55. }
    56. }

    这样子解析xml文件的代码不灵活,而且xml文件里的格式没有一个统一的写法就很麻烦,

    所以就需要约束xml文件的写法

    🌲DTD

    什么是约束

    • 用来限定xml文件中可使用的标签以及属性

    约束的分类

    • DTD
    • schema

    编写DTD约束的步骤

    1. 创建一个文件,这个文件的后缀名为.dtd
    2. 看xml文件中使用了哪些元素------ 可以定义元素
    3. 判断元素是简单元素还是复杂元素(简单元素:没有子元素。 复杂元素:有子元素的元素)

    引入本地约束

    引入DTD约束的三种方法

    • 引入本地dtd-------同上

    • 在xml文件内部引入

    • 引入网络dtd

    约束标签(元素)

     简单元素里面没有子元素,复杂元素里面有子元素

     约束属性

     

     

    🌻Schema

     schema和dtd的区别

    • schema约束文件也是一个xml文件,符合xml的语法,这个文件的后缀名.xsd

    • 一个xml中可以引用多个schema约束文件,多个schema使用名称空间区分(名称空间类似于java包名)

    • dtd里面元素类型的取值比较单一常见的是PCDATA类型,但是在schema里面可以支持很多个数据类型

    • schema 语法更加的复杂

     编写schema约束的步骤

    1. "1.0" encoding="UTF-8" ?>
    2. <schema
    3. xmlns="http://www.w3.org/2001/XMLSchema"
    4. targetNamespace="https://blog.csdn.net/HeyVirBbox"
    5. elementFormDefault="qualified">
    6. <element name="persons">
    7. <complexType>
    8. <sequence>
    9. <element name="person">
    10. <complexType>
    11. <sequence>
    12. <element name="name" type="string">element>
    13. <element name="age" type="string">element>
    14. sequence>
    15. complexType>
    16. element>
    17. sequence>
    18. complexType>
    19. element>
    20. schema>

    引入schema约束文件步骤

    1. "1.0" encoding="UTF-8" ?>
    2. <persons
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns="https://blog.csdn.net/HeyVirBbox"
    5. xsi:schemaLocation="https://blog.csdn.net/HeyVirBbox person.xsd"
    6. >
    7. <person>
    8. <name>张三name>
    9. <age>23age>
    10. person>
    11. persons>

     schema定义属性

  • 相关阅读:
    树状数组应用(AcWing 242,243,244)
    2024年2月个人工作生活总结
    Webhook 是什么?Webhook与API有什么区别
    bRPC works with iRDMA && ICE on Fedora 37
    Redis持久化-RDB和AOF
    SeataAT模式如何达到读已提交的隔离级别
    VMware16虚拟机添加硬盘(磁盘)和挂载硬盘(磁盘)
    七、克隆虚拟机、常见错误及解决方案
    百度智能云千帆Appbuilder全面升级!可玩性更强!速来体验!
    git冲突时拉取并覆盖本地代码
  • 原文地址:https://blog.csdn.net/HeyVIrBbox/article/details/126448334