300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 黑马全套Java教程(十一)

黑马全套Java教程(十一)

时间:2023-02-03 05:28:01

相关推荐

黑马全套Java教程(十一)

文章目录

40 反射40.1 单元测试40.2 反射40.3 注解40.4 动态代理41 XML41.1 XML41.2 XML解析技术41.3 XPath41.4 设计模式总结

黑马全套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优点

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

UserService.java

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

TestUserService.java

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

package d1_junit;import jdk.jfr.BooleanFlag;import org.junit.*;//测试类public class TestUserService {//修饰实例方法的@Beforepublic void before(){System.out.println("===before方法执行一次===");}@Afterpublic void after(){System.out.println("===after方法执行一次===");}//修饰静态方法@BeforeClasspublic static void beforeClass(){System.out.println("===beforeClass方法执行一次===");}@AfterClasspublic static void afterClass(){System.out.println("===afterClass方法执行一次===");}/*测试方法注意点1、必须是公开的,无参数,无返回值的方法2、测试方法必须使用@Test注解标记*/@Testpublic void testLoginName(){UserService userService = new UserService();String rs = userService.loginName("admin", "123456");//进行预期结果的正确性测试:断言Assert.assertEquals("您的功能业务可能出现问题", "登录成功!", rs);}@Testpublic void testSelectNames(){UserService userService = new UserService();userService.selectNames();}}

===beforeClass方法执行一次======before方法执行一次======after方法执行一次======before方法执行一次===5查询全部用户名成功!===after方法执行一次======afterClass方法执行一次===

40.2 反射

反射是指对于任何一个Class类,在运行的时候都可以直接得到这个类全部成分。

在运行时,可以直接得到这个类的构造器对象:Constructor

在运行时,可以直接得到这个类的成员变量对象:Field

在运行时,可以直接得到这个类的成员方法对象:Method

这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。

package d2_reflect_class;public class Test {public static void main(String[] args) throws ClassNotFoundException {//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 = new Student();Class c2 = s.getClass();System.out.println(c2);}}

class d2_reflect_class.Studentclass d2_reflect_class.Studentclass d2_reflect_class.Student

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

编程成Class文件进入运行阶段的时候,泛型会自动擦除反射是作用在运行时的技术,此时已经不存在泛型了

package d6_reflect_genericity;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;//反射:突破泛型的约束public class ReflectDemo {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {//需求:反射实现泛型擦除后,加入其他类型的元素ArrayList<String> lists1 = new ArrayList<>();ArrayList<Integer> lists2 = new ArrayList<>();System.out.println(lists1.getClass());System.out.println(lists2.getClass());System.out.println(lists1.getClass() == lists2.getClass());System.out.println("--------------------");ArrayList<Integer> lists3 = new ArrayList<>();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);}}

class java.util.ArrayListclass java.util.ArrayListtrue--------------------true[23, 22, 黑马]

案例:反射做通用框架

Student.java

package d7_reflect_framework;public class Student {private String name;private char sex;private int age;private String className;private String hobby;public Student(){}public Student(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;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public String getHobby() {return hobby;}public void setHobby(String hobby) {this.hobby = hobby;}}

Teacher.java

package d7_reflect_framework;public class Teacher {private String name;private char sex;private double salary;public Teacher() {}public Teacher(String name, char sex, double salary) {this.name = name;this.sex = sex;this.salary = salary;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}}

MybatisUtil.java

package d7_reflect_framework;import java.io.FileOutputStream;import java.io.PrintStream;import java.lang.reflect.Field;public class MybatisUtil {public static void save(Object obj) {try(PrintStream ps = new PrintStream(new FileOutputStream("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

package d7_reflect_framework;//目标:提供一个通用框架,支持保存所有对象的具体信息public class ReflectDemo {public static void main(String[] args) {Student s = new Student();s.setName("猪八戒");s.setClassName("西天跑路班");s.setAge(1000);s.setHobby("吃,睡");s.setSex('男');MybatisUtil.save(s);Teacher t = new Teacher();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

package d8_annotation;public @interface MyBook {String name();String[] authors();double price();}

AnnotationDemo1.java

package d8_annotation;//目标:自定义注解@MyBook(name="《精通JavaSE》", authors = {"zdb", "zzz"}, price = 199)public class AnnotationDemo1 {@MyBook(name="《精通JavaSE》", authors = {"zdb", "zzz"}, price = 199)private AnnotationDemo1(){}@MyBook(name="《精通JavaSE》", authors = {"zdb", "zzz"}, price = 199)public static void main(String[] args) {@MyBook(name="《精通JavaSE》", authors = {"zdb", "zzz"}, price = 199)int age = 21;}}

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

Book.java

package d8_annotation;public @interface Book {String value(); //特殊属性double price() default 9.9;}

元注解:注解注解的注解

元注解有两个:

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

MyTest.java

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

AnnotationDemo2.java

package d8_annotation;//目标:认识元注解//@MyTest //只能注解方法和成员变量public class AnnotationDemo2 {@MyTestprivate String name;@MyTestpublic void test(){}public static void main(String[] args) {}}

注解的解析:注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,存在注解就解析出内容。

bookk.java

package d8_annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface bookk {String value();double price() default 100;String[] author();}

AnnotationDemo3.java

package d8_annotation;import org.junit.Test;import java.lang.reflect.Method;import java.util.Arrays;//目标:完成注解的解析public class AnnotationDemo3 {@Testpublic static void main(String[] args) throws NoSuchMethodException {//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"})class BookStore{@bookk(value = "<三少爷的剑>", price = 22, author = {"zzz", "aaa"})public void test(){}}

40.4 动态代理

Star.java

package d9_proxy;public class Star implements Skill{private String name;public Star(String name){this.name = name;}@Overridepublic void jump(){System.out.println(name + "跳舞");}@Overridepublic void sing(){System.out.println(name + "唱歌");}}

Skill接口

package d9_proxy;public interface Skill {void jump();void sing();}

StarAgentProxy.java

package d9_proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class StarAgentProxy {//设计一个方法来返回一个明星对象的代理对象public static Skill getProxy(Star obj){//为杨超越这个对象,生成一个代理对象return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("收首付款。。。");//真正的让杨超越去唱歌和跳舞。。。//method 正在调用的方法对象 args代表这个方法的参数Object rs = method.invoke(obj, args);System.out.println("收尾款。。。");return rs;}});}}

Test.java

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

UserService.java

package d10_proxy2;public interface UserService {String login(String loginName, String passWord);void deleteUser();String selectUsers();}

UserServiceImpl.java

package d10_proxy2;public class UserServiceImpl implements UserService{@Overridepublic String login(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;}@Overridepublic void deleteUser() {try {System.out.println("您正在删除用户数据中。。。");Thread.sleep(2500);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic String selectUsers() {String rs = "查询了10000个用户数据。。。";try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return rs;}}

ProxyUtil.java

package d10_proxy2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyUtil {//通过一个静态方法,为用户业务对象返回一个代理对象public static UserService getProxy(UserService obj){return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {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

package d10_proxy2;//掌握使用动态代理解决问题,理解使用动态代理的优势public class Test {public static void main(String[] args) {UserService userService = ProxyUtil.getProxy(new UserServiceImpl());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的问题:

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

schema约束

例:

41.2 XML解析技术

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

两种解析方式:

SAX解析DOM解析

案例:dom4j解析

package d1_dom4j;/** 目标:学会使用dom4j解析XML文件中的数据* 1、导入dom4j框架* 2、准备一个XML文件*/import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.junit.Test;import java.io.File;import java.io.InputStream;public class Dom4JHelloWorldDemo1 {@Testpublic void parseXMLData() throws DocumentException {//1、创建一个Dom4j的解析对象,代表了整个dom4j框架SAXReader saxReader = new SAXReader();//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());}}

package d1_dom4j;/** 目标:学会使用dom4j解析XML文件中的数据* 1、导入dom4j框架* 2、准备一个XML文件*/import org.dom4j.Attribute;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.junit.Test;import org.w3c.dom.Attr;import java.io.File;import java.io.InputStream;import java.util.List;public class Dom4JHelloWorldDemo1 {@Testpublic void parseXMLData() throws DocumentException {//1、创建一个Dom4j的解析对象,代表了整个dom4j框架SAXReader saxReader = new SAXReader();//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());}}

案例:

package d1_dom4j;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.junit.Test;import java.util.ArrayList;import java.util.List;//需求:解析XML中的数据成为一个List集合对象public class Dom4JTest2 {@Testpublic void parseToList() throws DocumentException {//需求:解析XML中的数据称为一个List集合对象//1、导入框架//2、创建SaxReader对象SAXReader saxReader = new SAXReader();//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 = new ArrayList<>();//7、遍历Contact子元素for (Element contactEle : contactEles) {//8、每个子元素都是一个联系人对象Contact contact = new Contact();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 设计模式

工厂模式

总结

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。