0


黑马全套Java教程(十一)

文章目录

黑马全套Java教程(一)
黑马全套Java教程(二)
黑马全套Java教程(三)
黑马全套Java教程(四)
黑马全套Java教程(五)
黑马全套Java教程(六)
黑马全套Java教程(七)
黑马全套Java教程(八)
黑马全套Java教程(九)

40 反射

40.1 单元测试

单元测试:针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,进而检查方法的正确性

目前测试方法是怎么进行的,存在什么问题:

  • 只有一个main方法,如果一个方法的测试失败了,其他方法测试会受到影响
  • 无法得到测试的结果报告,需要程序员自己去观察测试是否成功
  • 无法实现自动化测试

Junit单元测试框架:JUnit是使用Java语言实现的单元测试框架,它是开源的,Java开发者都应当学习并使用JUnit编写单元测试。此外,几乎所有的IDE工具都继承了JUnit,这样我们就可以直接在IDE中编写并运行JUnit,这样我们就可以直接在IDE中编写并运行JUnit测试,JUnit目前最新版本是。

JUnit优点

  1. JUnit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法。
  2. Junit可以生成全部方法的测试报告。
  3. 单元测试中的某个方法测试失败了,不会影响其他测试方法的测试。

在这里插入图片描述
UserService.java

packaged1_junit;//业务方法publicclassUserService{publicStringloginName(String loginName,String passWord){if("admin".equals(loginName)&&"123456".equals(passWord)){return"登录成功!";}else{return"用户名或密码出错!";}}publicvoidselectNames(){System.out.println(10/0);System.out.println("查询全部用户名成功!");}}

TestUserService.java

packaged1_junit;importorg.junit.Assert;importorg.junit.Test;//测试类publicclassTestUserService{/*测试方法
        注意点
            1、必须是公开的,无参数,无返回值的方法
            2、测试方法必须使用@Test注解标记
     */@TestpublicvoidtestLoginName(){UserService userService =newUserService();String rs = userService.loginName("admin","123456");//进行预期结果的正确性测试:断言Assert.assertEquals("您的功能业务可能出现问题","登录成功!", rs);}@TestpublicvoidtestSelectNames(){UserService userService =newUserService();
        userService.selectNames();}}

在这里插入图片描述

packaged1_junit;importjdk.jfr.BooleanFlag;importorg.junit.*;//测试类publicclassTestUserService{//修饰实例方法的@Beforepublicvoidbefore(){System.out.println("===before方法执行一次===");}@Afterpublicvoidafter(){System.out.println("===after方法执行一次===");}//修饰静态方法@BeforeClasspublicstaticvoidbeforeClass(){System.out.println("===beforeClass方法执行一次===");}@AfterClasspublicstaticvoidafterClass(){System.out.println("===afterClass方法执行一次===");}/*测试方法
        注意点
            1、必须是公开的,无参数,无返回值的方法
            2、测试方法必须使用@Test注解标记
     */@TestpublicvoidtestLoginName(){UserService userService =newUserService();String rs = userService.loginName("admin","123456");//进行预期结果的正确性测试:断言Assert.assertEquals("您的功能业务可能出现问题","登录成功!", rs);}@TestpublicvoidtestSelectNames(){UserService userService =newUserService();
        userService.selectNames();}}
===beforeClass方法执行一次======before方法执行一次======after方法执行一次======before方法执行一次===5
查询全部用户名成功!
===after方法执行一次======afterClass方法执行一次===

在这里插入图片描述

40.2 反射

反射是指对于任何一个Class类,在运行的时候都可以直接得到这个类全部成分。
在运行时,可以直接得到这个类的构造器对象:Constructor
在运行时,可以直接得到这个类的成员变量对象:Field
在运行时,可以直接得到这个类的成员方法对象:Method
这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。

在这里插入图片描述

在这里插入图片描述

packaged2_reflect_class;publicclassTest{publicstaticvoidmain(String[] args)throwsClassNotFoundException{//1. Class类中的静态方法:forName(全限名:包名+类名)Class c =Class.forName("d2_reflect_class.Student");System.out.println(c);//Student.class//2. 类名.classClass c1 =Student.class;System.out.println(c1);//3. 对象.getClass()获取对象对应类的Class对象Student s =newStudent();Class c2 = s.getClass();System.out.println(c2);}}
classd2_reflect_class.Studentclassd2_reflect_class.Studentclassd2_reflect_class.Student

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

反射为何可以给约定了泛型的集合存入其他类型的元素?

  • 编程成Class文件进入运行阶段的时候,泛型会自动擦除
  • 反射是作用在运行时的技术,此时已经不存在泛型了
packaged6_reflect_genericity;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.ArrayList;//反射:突破泛型的约束publicclassReflectDemo{publicstaticvoidmain(String[] args)throwsNoSuchMethodException,InvocationTargetException,IllegalAccessException{//需求:反射实现泛型擦除后,加入其他类型的元素ArrayList<String> lists1 =newArrayList<>();ArrayList<Integer> lists2 =newArrayList<>();System.out.println(lists1.getClass());System.out.println(lists2.getClass());System.out.println(lists1.getClass()== lists2.getClass());System.out.println("--------------------");ArrayList<Integer> lists3 =newArrayList<>();
        lists3.add(23);
        lists3.add(22);//list.add("asdas");Class c = lists3.getClass();//定位c类中的add方法Method add = c.getDeclaredMethod("add",Object.class);boolean rs =(boolean)add.invoke(lists3,"黑马");//是否添加成功System.out.println(rs);System.out.println(lists3);ArrayList list4 = lists3;
        list4.add("白马");
        list4.add(false);}}
classjava.util.ArrayListclassjava.util.ArrayListtrue--------------------true[23,22, 黑马]

案例:反射做通用框架
在这里插入图片描述
Student.java

packaged7_reflect_framework;publicclassStudent{privateString name;privatechar sex;privateint age;privateString className;privateString hobby;publicStudent(){}publicStudent(String name,char sex,int age,String className,String hobby){this.name = name;this.sex = sex;this.age = age;this.className = className;this.hobby = hobby;}publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicchargetSex(){return sex;}publicvoidsetSex(char sex){this.sex = sex;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age = age;}publicStringgetClassName(){return className;}publicvoidsetClassName(String className){this.className = className;}publicStringgetHobby(){return hobby;}publicvoidsetHobby(String hobby){this.hobby = hobby;}}

Teacher.java

packaged7_reflect_framework;publicclassTeacher{privateString name;privatechar sex;privatedouble salary;publicTeacher(){}publicTeacher(String name,char sex,double salary){this.name = name;this.sex = sex;this.salary = salary;}publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicchargetSex(){return sex;}publicvoidsetSex(char sex){this.sex = sex;}publicdoublegetSalary(){return salary;}publicvoidsetSalary(double salary){this.salary = salary;}}

MybatisUtil.java

packaged7_reflect_framework;importjava.io.FileOutputStream;importjava.io.PrintStream;importjava.lang.reflect.Field;publicclassMybatisUtil{publicstaticvoidsave(Object obj){try(PrintStream ps =newPrintStream(newFileOutputStream("junit-app/src/data.txt",true));){//1. 提取这个对象的全部变量:只有反射可以解决Class c = obj.getClass();//c.getSimpleName()获取当前类名   c.getName获取全限名:包名+类名
            ps.println("==========="+ c.getSimpleName()+"============");//2. 提取它的全部成员变量Field[] fields = c.getDeclaredFields();//3. 获取成员变量的信息for(Field field : fields){String name = field.getName();//提取本成员变量在obj中的值(取值)
                field.setAccessible(true);String value = field.get(obj)+"";
                ps.println(name +"="+ value);}}catch(Exception e){
            e.printStackTrace();}}}

ReflectDemo.java

packaged7_reflect_framework;//目标:提供一个通用框架,支持保存所有对象的具体信息publicclassReflectDemo{publicstaticvoidmain(String[] args){Student s =newStudent();
        s.setName("猪八戒");
        s.setClassName("西天跑路班");
        s.setAge(1000);
        s.setHobby("吃,睡");
        s.setSex('男');MybatisUtil.save(s);Teacher t =newTeacher();
        t.setName("波仔");
        t.setSex('男');
        t.setSalary(6000);MybatisUtil.save(t);}}

在这里插入图片描述

40.3 注解

Java注解又称Java标注,是JDK5.09引入的一种注释机制。Java语言中的类、构造器、方法、成员变量、参数都可以被注解进行标注。
在这里插入图片描述
注解的作用:对Java中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定。例如:JUint框架中,标记了注解@Test的方法就可以被当成测试方法执行,而没有标记的就不能当成测试方法执行。

自定义注解格式:

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

例:
MyBook.java

packaged8_annotation;public@interfaceMyBook{Stringname();String[]authors();doubleprice();}

AnnotationDemo1.java

packaged8_annotation;//目标:自定义注解@MyBook(name="《精通JavaSE》", authors ={"zdb","zzz"}, price =199)publicclassAnnotationDemo1{@MyBook(name="《精通JavaSE》", authors ={"zdb","zzz"}, price =199)privateAnnotationDemo1(){}@MyBook(name="《精通JavaSE》", authors ={"zdb","zzz"}, price =199)publicstaticvoidmain(String[] args){@MyBook(name="《精通JavaSE》", authors ={"zdb","zzz"}, price =199)int age =21;}}

特殊属性:value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写。但是如果有多个属性,且多个属性没有默认值,那么value名称是不能省略的。
Book.java

packaged8_annotation;public@interfaceBook{Stringvalue();//特殊属性doubleprice()default9.9;}

在这里插入图片描述

元注解:注解注解的注解

元注解有两个:

  1. @Target:约束自定义注解只能在哪些地方使用
  2. @Retention:声明注解的生命周期

MyTest.java

packaged8_annotation;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target({ElementType.METHOD,ElementType.FIELD})//元注解@Retention(RetentionPolicy.RUNTIME)//一直活着,在运行阶段这个注解也不消失public@interfaceMyTest{}

AnnotationDemo2.java

packaged8_annotation;//目标:认识元注解//@MyTest  //只能注解方法和成员变量publicclassAnnotationDemo2{@MyTestprivateString name;@MyTestpublicvoidtest(){}publicstaticvoidmain(String[] args){}}

在这里插入图片描述

注解的解析:注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,存在注解就解析出内容。
在这里插入图片描述
在这里插入图片描述

bookk.java

packaged8_annotation;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public@interface bookk {Stringvalue();doubleprice()default100;String[]author();}

AnnotationDemo3.java

packaged8_annotation;importorg.junit.Test;importjava.lang.reflect.Method;importjava.util.Arrays;//目标:完成注解的解析publicclassAnnotationDemo3{@Testpublicstaticvoidmain(String[] args)throwsNoSuchMethodException{//1. 先得到类对象Class c =BookStore.class;Method m = c.getDeclaredMethod("test");//2. 判断这个类上面是否存在这个注解if(c.isAnnotationPresent(bookk.class)){//3. 直接获取该注解对象
            bookk book =(bookk)c.getDeclaredAnnotation(bookk.class);System.out.println(book.value());System.out.println(book.price());System.out.println(Arrays.toString(book.author()));}}}@bookk(value ="<情深深雨濛濛>", price =99.9, author ={"zzz","aaa"})classBookStore{@bookk(value ="<三少爷的剑>", price =22, author ={"zzz","aaa"})publicvoidtest(){}}

40.4 动态代理

在这里插入图片描述

Star.java

packaged9_proxy;publicclassStarimplementsSkill{privateString name;publicStar(String name){this.name = name;}@Overridepublicvoidjump(){System.out.println(name +"跳舞");}@Overridepublicvoidsing(){System.out.println(name +"唱歌");}}

Skill接口

packaged9_proxy;publicinterfaceSkill{voidjump();voidsing();}

StarAgentProxy.java

packaged9_proxy;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;publicclassStarAgentProxy{//设计一个方法来返回一个明星对象的代理对象publicstaticSkillgetProxy(Star obj){//为杨超越这个对象,生成一个代理对象return(Skill)Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),newInvocationHandler(){@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{System.out.println("收首付款。。。");//真正的让杨超越去唱歌和跳舞。。。//method  正在调用的方法对象    args代表这个方法的参数Object rs = method.invoke(obj, args);System.out.println("收尾款。。。");return rs;}});}}

Test.java

packaged9_proxy;//目标:学习开发出一个动态代理的对象出来,理解动态代理的执行流程publicclassTest{publicstaticvoidmain(String[] args){//1. 创建一个对象(杨超越)  对象的类必须实现接口Star s =newStar("杨超越");// 为杨超越对象,生成一个代理对象(经纪人)Skill s2 =StarAgentProxy.getProxy(s);
        s2.jump();
        s2.sing();}}

在这里插入图片描述

UserService.java

packaged10_proxy2;publicinterfaceUserService{Stringlogin(String loginName,String passWord);voiddeleteUser();StringselectUsers();}

UserServiceImpl.java

packaged10_proxy2;publicclassUserServiceImplimplementsUserService{@OverridepublicStringlogin(String loginName,String passWord){String rs ="登录名和密码错误";if("admin".equals(loginName)&&"123456".equals(passWord)){
            rs ="登录成功";}try{Thread.sleep(1000);}catch(InterruptedException e){
            e.printStackTrace();}return rs;}@OverridepublicvoiddeleteUser(){try{System.out.println("您正在删除用户数据中。。。");Thread.sleep(2500);}catch(InterruptedException e){
            e.printStackTrace();}}@OverridepublicStringselectUsers(){String rs ="查询了10000个用户数据。。。";try{Thread.sleep(3000);}catch(InterruptedException e){
            e.printStackTrace();}return rs;}}

ProxyUtil.java

packaged10_proxy2;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;publicclassProxyUtil{//通过一个静态方法,为用户业务对象返回一个代理对象publicstaticUserServicegetProxy(UserService obj){return(UserService)Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),newInvocationHandler(){@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{long startTime =System.currentTimeMillis();//真正触发对象的行为执行的Object rs = method.invoke(obj, args);long endTime =System.currentTimeMillis();System.out.println(method.getName()+"方法耗时:"+(endTime - startTime)/1000.0+"s");return rs;}});}}

Test.java

packaged10_proxy2;//掌握使用动态代理解决问题,理解使用动态代理的优势publicclassTest{publicstaticvoidmain(String[] args){UserService userService =ProxyUtil.getProxy(newUserServiceImpl());System.out.println(userService.login("admin","123456"));System.out.println(userService.selectUsers());
        userService.deleteUser();}}

在这里插入图片描述

41 XML

41.1 XML

XML是可扩展标记语言的缩写,它是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据

  • 纯文本,默认使用UTF-8编码;二是可嵌套
  • 如果把XML内容存为文件,那么它就是一个XML文件
  • XML的使用场景:XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的消息在这里插入图片描述语法规则:在这里插入图片描述在这里插入图片描述在这里插入图片描述

hello_world.xml

<?xml version="1.0" encoding="UTF-8" ?><!-- 我是注释: 跟标签只能有一个--><student><name>女儿国网</name><sex>女</sex><hobby>唐僧</hobby><info><age>30</age><addr>女儿国</addr></info><sql>
        select * from user where age &lt; 18;
        select * from user where age &lt; 18 &amp;&amp; age > 10;
        <![CDATA[
                select * from user where age < 18;
        ]]></sql></student>

在这里插入图片描述

文档约束:是用来限定xml文件中的标签以及属性应该怎么写;以此强制约束程序员必须按照文档约束的规定来编写xml文件。
在这里插入图片描述

DTD约束文档
在这里插入图片描述
例:
在这里插入图片描述
在这里插入图片描述
DTD的问题:

  1. 可以约束XML文件的编写
  2. 不能约束具体的数据类型

schema约束
在这里插入图片描述

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

41.2 XML解析技术

什么是XML解析:使用程序读取XML中的数据

两种解析方式:

  1. SAX解析
  2. DOM解析

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

在这里插入图片描述

案例:dom4j解析

packaged1_dom4j;/*
 *  目标:学会使用dom4j解析XML文件中的数据
 *  1、导入dom4j框架
 *  2、准备一个XML文件
 */importorg.dom4j.Document;importorg.dom4j.DocumentException;importorg.dom4j.Element;importorg.dom4j.io.SAXReader;importorg.junit.Test;importjava.io.File;importjava.io.InputStream;publicclassDom4JHelloWorldDemo1{@TestpublicvoidparseXMLData()throwsDocumentException{//1、创建一个Dom4j的解析对象,代表了整个dom4j框架SAXReader saxReader =newSAXReader();//2、把XML文件加载到内存中成为一个Document文档对象//Document document = saxReader.read(new File("xml-app\\src\\Contacts.xml"));   //需要通过模块名定位//直接在src下寻找文件,改了模块名没有影响InputStream is =Dom4JHelloWorldDemo1.class.getResourceAsStream("/Contacts.xml");Document document = saxReader.read(is);//3、获取根元素对象Element root = document.getRootElement();System.out.println(root.getName());}}

在这里插入图片描述

packaged1_dom4j;/*
 *  目标:学会使用dom4j解析XML文件中的数据
 *  1、导入dom4j框架
 *  2、准备一个XML文件
 */importorg.dom4j.Attribute;importorg.dom4j.Document;importorg.dom4j.DocumentException;importorg.dom4j.Element;importorg.dom4j.io.SAXReader;importorg.junit.Test;importorg.w3c.dom.Attr;importjava.io.File;importjava.io.InputStream;importjava.util.List;publicclassDom4JHelloWorldDemo1{@TestpublicvoidparseXMLData()throwsDocumentException{//1、创建一个Dom4j的解析对象,代表了整个dom4j框架SAXReader saxReader =newSAXReader();//2、把XML文件加载到内存中成为一个Document文档对象//Document document = saxReader.read(new File("xml-app\\src\\Contacts.xml"));   //需要通过模块名定位//直接在src下寻找文件,改了模块名没有影响InputStream is =Dom4JHelloWorldDemo1.class.getResourceAsStream("/Contacts.xml");Document document = saxReader.read(is);//3、获取根元素对象Element root = document.getRootElement();System.out.println(root.getName());//4、拿根元素下的全部子元素对象List<Element> sonEles = root.elements();for(Element sonEle : sonEles){System.out.println(sonEle.getName());}//拿到某个子元素Element userEle = root.element("user");System.out.println(userEle.getName());//默认提取第一个子元素对象Element contact = root.element("contact");//获取子元素文本System.out.println(contact.elementText("name"));//去掉前后空格System.out.println(contact.elementTextTrim("name"));//根据元素获取属性值Attribute idAttr = contact.attribute("id");System.out.println(idAttr.getName()+"----->"+ idAttr.getValue());//直接提取属性值System.out.println(contact.attributeValue("id"));System.out.println(contact.attributeValue("vip"));//获取当前元素下的子元素对象Element email = contact.element("email");System.out.println(email.getText());}}

案例:
在这里插入图片描述

packaged1_dom4j;importorg.dom4j.Document;importorg.dom4j.DocumentException;importorg.dom4j.Element;importorg.dom4j.io.SAXReader;importorg.junit.Test;importjava.util.ArrayList;importjava.util.List;//需求:解析XML中的数据成为一个List集合对象publicclassDom4JTest2{@TestpublicvoidparseToList()throwsDocumentException{//需求:解析XML中的数据称为一个List集合对象//1、导入框架//2、创建SaxReader对象SAXReader saxReader =newSAXReader();//3、加载XML文件成为文档对象Document对象Document document = saxReader.read(Dom4JTest2.class.getResourceAsStream("/Contacts.xml"));//4、先拿根元素Element root = document.getRootElement();//5、提取contact子元素List<Element> contactEles = root.elements("contact");//6、准备一个ArrayList集合封装联系人信息List<Contact> contacts =newArrayList<>();//7、遍历Contact子元素for(Element contactEle : contactEles){//8、每个子元素都是一个联系人对象Contact contact =newContact();
            contact.setId(Integer.valueOf(contactEle.attributeValue("id")));
            contact.setVip(Boolean.valueOf(contactEle.attributeValue("vip")));
            contact.setName(contactEle.attributeValue("Name"));
            contact.setGender(contactEle.attributeValue("gender").charAt(0));//取一个字符
            contact.setEmail(contactEle.attributeValue("email"));//9、把联系人对象数据加入到List集合
            contacts.add(contact);}//10、遍历List集合for(Contact contact : contacts){System.out.println(contact);}}}

41.3 XPath

XPath使用路径表达式来定位XML文档中的元素节点或属性节点
在这里插入图片描述

41.4 设计模式

工厂模式
在这里插入图片描述

在这里插入图片描述

总结

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

标签: java junit 单元测试

本文转载自: https://blog.csdn.net/qq_39236499/article/details/127726483
版权归原作者 zdb呀 所有, 如有侵权,请联系我们删除。

“黑马全套Java教程(十一)”的评论:

还没有评论