一、反射

1.1 反射概念

  1. 概念:反射式先获取对象,由对象中的指定方法,获取其指定类中的成员方法、成员属性和构造方法。
  2. 对象:反射中的对象全部指的是字节码对象,字节码对象称为Class类声明的对象。

1.2 获取字节码对象的方法

  1. 方式1:通过类名.class获取
  1. Class<?> clazz = 类名.class
  2. 举例:
  3. Class<?> clazz = Person.class;
  1. 方式2:通过该类的对象获取字节码对象
  1. 类名 对象 = new 类名();
  2. Class<?> clazz = 对象.getClass();
  3. //举例:
  4. Person p1 = new Person();
  5. Class<?> clazz = p1.getClass();
  1. 使用Class类中提供的静态方法,可以通过类名的全路径获取字节码对象,推荐方式
  1. Classs<?> clazz = Class.forName("类的全路径");
  2. //举例:
  3. Class<?> clazz = Class.forName("com.woniuxy.demo.Person");

1.3 反射涉及的方法

  1. 使用反射获取构造方法
  1. //1、获取公共的构造方法,后面的参数,填写的是构造方法的数据类型的字节码对象,如果想要调用无参构造传入null即可,也可以直接空着
  2. getConstructor(Class<?>...parameterTypes);
  3. //2、获取私有的构造方法,后面的参数,填写的是构造方法的数据类型的字节码对象,如果想要调用无参构造传入null即可,也可以直接空着
  4. getDeclaredConstrcutor(Class<?>...parameterTypes);
  5. //注意:如果是私有的构造方法,需要在破解私有,使用方法
  6. c.setAccessible(true);
  7. //通过Class字节码对象调用获取构造方法的方法,获取的是构造方法的对象,用该对象执行newInstance()对应的对象,后面的参数表示:对应构造方法需要的实际参数,这个参数和上面的getConstructor()方法中的数据类型参数要对应
  8. newInstance(Object...initiargs);
  1. 使用反射获取成员方法
  1. //1、获取公共的成员方法,括号里面由两个参数组成部分,第一个参数表示方法名称,第二个是可变参数,用于传递方法的形式参数数据类型的字节码对象.
  2. getMethod(String name,Class<?>...parameterTypes);
  3. //2、获取私有的成员方法,,括号里面由两个参数组成部分,第一个参数表示方法名称,第二个是可变参数,用于传递方法的形式参数数据类型的字节码对象.
  4. getDeclaredMethod(String name,Class<?>...parameterTypes);
  5. //需要破解
  6. method.setAccessible(true);
  7. //在Method类中,定义了invoke方法,该方法用于执行字节码对象对应的对象的成员方法
  8. //第一个参数:对应类的对象
  9. //第二个参数:对应方法需要的实际参数,需要和Method中的形式参数对应
  10. invoke(Object obj,Object...args);
  1. 获取成员属性
  1. //1、获取公有的成员属性,括号中的参数表示成员属性的名称
  2. getField(String name)
  3. //2、获取私有的成员属性,括号中的参数表示成员属性的名称
  4. getDeclaredField(String name)
  5. //需要破解私有
  6. method.setAccessible(true);
  7. //在Field类中,定义了get(object obj)方法,用于获取字节码对象对应类中的成员属性值
  8. //参数:哪一个对象进行调用成员属性
  9. get(Object obj)

二、XML文件

2.1 概念

  1. XML文件的全称可扩展的标记语言,XML文件由一些标签组成,可扩展的标签,标签和属性可以自定义,程序员可以根据自己的实际需求定义标签、属性及语言结构

  2. XML文件本质上用来作为配置文件使用,和之前的文件:properties配置文件,txt文件作用类似,在实际开发中,一般数据的结构都是比较复杂的层级结构,比如: ```xml

    <四川> <成都> <金牛区></金牛区> <武侯区></武侯区> <青羊区></青羊区> </成都> </四川> <重庆> <渝北区></渝北区> <渝中区></渝中区> <江北区></江北区> </重庆>

  1. <field>
  2. <field-name></field-name>
  3. <field-type></field-type>
  4. </field>
  5. </class>
  6. <class>
  7. <class-name></class-name>
  8. </class>

  1. <a name="14963c09"></a>
  2. #### 2.2 XML文件的组成
  3. 1.
  4. 声明:每一个xml文件声明部分必须顶格,不能允许任何内容出现,也不能出现注释
  5. ```xml
  6. <?xml version="1.0" encoding="utf-8" ?>
  1. 注释内容
    1. <!--注释的内容部分,可以多行-->
  1. 标签:将单词或者单词组合放在尖括号里面,在两个尖括号之间可以存放文本内容,标签名称自定义
    1. <name></name>
  1. 属性:在开始标签里面,新增的属性名称和属性值,属性名称自定义即可
    1. <user name = "李四" age = "18"></user>
  1. 转义字符:因为标记语言和某些运算发存在冲突,因此需要直接显示运算符,需要转义
    1. &amp;---->&
    2. &gt;----->大于符号
    3. &lt;----->小于符号
  1. 内容部分:在两个标签之间的文本,称为内容部分
    1. <user>
    2. <user-name>张三</user-name>
    3. <user-age>18</user-age>
    4. </user>
  1. CDATA区:数据区,一般来说,如果想要在页面展示标签内容,需要CDATA区

2.3 XML解析

  1. DOM解析方式:使用DOM解析方式,一开始会将所有的XML文件标签全部解析到内存中,生成文档树结构
    优点:解析速度快
    缺点:耗内存

  2. SAX解析方式:按需解析,需要使用到哪一个标签,然后解析到哪一个标签,没有涉及到的标签不解析
    优点:内存消耗小
    缺点:解析速度慢

2.4 XML解析的操作

步骤:

  1. public class XMLDemo1 {
  2. public static void main(String[] args) throws Exception{
  3. //1、获取工厂
  4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  5. //2、通过工厂获取解析器
  6. DocumentBuilder builder = factory.newDocumentBuilder();
  7. //3、通过解析器获取文档树
  8. Document document = builder.parse(new File("src/user.xml"));
  9. System.out.println(document);
  10. }
  11. }
  1. 获取元素

    1. public class QueryElement {
    2. public static void main(String[] args) throws Exception{
    3. //1、获取工厂
    4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    5. //2、获取解析器
    6. DocumentBuilder builder = factory.newDocumentBuilder();
    7. //3、获取文档树
    8. Document document = builder.parse(new File("src/user.xml"));
    9. //获取指定的标签,如果根据标签名称获取,则表示获取的是相同标签名的集合
    10. NodeList nodeList = document.getElementsByTagName("user-name");
    11. //从集合中获取指定的标签
    12. Node node = nodeList.item(0);
    13. //获取节点中的文本内容
    14. String text = node.getTextContent();
    15. System.out.println(text);
    16. }
    17. }
  1. 修改元素

    1. public class UpdateElement {
    2. public static void main(String[] args) throws Exception{
    3. //1、获取工厂
    4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    5. //2、获取解析器
    6. DocumentBuilder builder = factory.newDocumentBuilder();
    7. //3、获取文档树
    8. Document document = builder.parse(new File("src/user.xml"));
    9. //根据标签名称获取标签
    10. NodeList nodeList = document.getElementsByTagName("user-name");
    11. //获取指定的标签
    12. Node node = nodeList.item(0);
    13. //修改文本属性值
    14. node.setTextContent("张三四");
    15. //获取转换流的工厂对象
    16. TransformerFactory transformerFactory = TransformerFactory.newInstance();
    17. //将工厂对象获取转换器
    18. Transformer transformer = transformerFactory.newTransformer();
    19. //将内存中的文档树更新到硬盘中
    20. /*
    21. 第一个参数:表示内存中的文档树,作为源数据
    22. 第二个参数:表示结果树,作为硬盘中的结果
    23. */
    24. transformer.transform(new DOMSource(document),new StreamResult(new File("src/user.xml")));
    25. }
    26. }
  1. 新增元素
    第一种方式:在指定的父标签下,新增子标签,只能新增在最后位置

    1. public class CreateElement {
    2. public static void main(String[] args) throws Exception{
    3. //获取工厂
    4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    5. //获取解析器
    6. DocumentBuilder builder = factory.newDocumentBuilder();
    7. //获取文档树
    8. Document document = builder.parse(new File("src/user.xml"));
    9. //新增标签
    10. Element e = document.createElement("account");
    11. e.setTextContent("1000");
    12. //找到要放入的父标签
    13. NodeList nodeList = document.getElementsByTagName("u");
    14. Node parent = nodeList.item(0);
    15. //将新增标签挂载到父标签内
    16. parent.appendChild(e);
    17. //更新到硬盘中
    18. TransformerFactory transformerFactory = TransformerFactory.newInstance();
    19. Transformer transformer = transformerFactory.newTransformer();
    20. transformer.transform(new DOMSource(document),new StreamResult(new File("src/user.xml")));
    21. }
    22. }


第二种方式:想要将新标签放置在指定父标签下的任意位置

  1. public class CreateElement {
  2. public static void main(String[] args) throws Exception{
  3. method2();
  4. }
  5. public static void method2() throws Exception{
  6. //获取工厂
  7. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  8. DocumentBuilder builder = factory.newDocumentBuilder();
  9. Document document = builder.parse(new File("src/user.xml"));
  10. //新增标签
  11. Element e = document.createElement("tel");
  12. e.setTextContent("1100");
  13. //获取要放入新标签的后面的兄弟标签
  14. NodeList nodeLlist = document.getElementsByTagName("user-age");
  15. Node node = nodeLlist.item(0);
  16. //获取父标签
  17. NodeList list = document.getElementsByTagName("u");
  18. Node parent = list.item(0);
  19. //通过父标签添加子标签,需要指定位置
  20. /*
  21. 第一个参数:兄弟节点
  22. 第二个参数:要放入新节点的后面兄弟节点
  23. */
  24. parent.insertBefore(e,node);
  25. //将内存中的数据写出到硬盘中
  26. TransformerFactory transformerFactory = TransformerFactory.newInstance();
  27. Transformer transformer = transformerFactory.newTransformer();
  28. transformer.transform(new DOMSource(document),new StreamResult(new File("src/user.xml")));
  29. }
  30. }
  1. 删除元素

    1. public class DeleteElement {
    2. public static void main(String[] args) throws Exception{
    3. //获取文档树
    4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    5. DocumentBuilder builder = factory.newDocumentBuilder();
    6. Document document = builder.parse(new File("src/user.xml"));
    7. //获取指定元素标签
    8. NodeList nodeList = document.getElementsByTagName("tel");
    9. Node node = nodeList.item(0);
    10. //删除
    11. node.getParentNode().removeChild(node);
    12. //更新到硬盘中
    13. TransformerFactory transformerFactory = TransformerFactory.newInstance();
    14. Transformer transformer = transformerFactory.newTransformer();
    15. transformer.transform(new DOMSource(document),new StreamResult(new File("src/user.xml")));
    16. }
    17. }
  1. 将公共的部分抽取成工具类

    1. public class XMLUtils {
    2. public static Document getNode(String fileName) throws Exception{
    3. //获取文档树
    4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    5. DocumentBuilder builder = factory.newDocumentBuilder();
    6. Document document = builder.parse(new File(fileName));
    7. return document;
    8. }
    9. public static void flushData(String fileName,Document document) throws Exception{
    10. TransformerFactory transformerFactory = TransformerFactory.newInstance();
    11. Transformer transformer = transformerFactory.newTransformer();
    12. transformer.transform(new DOMSource(document),new StreamResult(new File(fileName)));
    13. }
    14. }

2.5 用xml文件封装JDBC工具类

  1. public class JDBCUtils {
  2. //声明四个变量
  3. private static String driver;
  4. private static String url;
  5. private static String username;
  6. private static String password;
  7. //使用静态代码块实现获取xml文件中的数据及注册驱动
  8. static{
  9. try {
  10. //读取xml配置文件
  11. Document document = XMLUtils.getNode("src/db.xml");
  12. driver = document.getElementsByTagName("driver").item(0).getTextContent();
  13. url = document.getElementsByTagName("url").item(0).getTextContent();
  14. username = document.getElementsByTagName("username").item(0).getTextContent();
  15. password = document.getElementsByTagName("password").item(0).getTextContent();
  16. //注册驱动
  17. Class.forName(driver);
  18. }catch (Exception e){
  19. e.printStackTrace();
  20. }
  21. }
  22. //获取连接
  23. public static Connection getConn(){
  24. try {
  25. return DriverManager.getConnection(url,username,password);
  26. }catch (Exception e){
  27. e.printStackTrace();
  28. }
  29. return null;
  30. }
  31. //关闭资源
  32. public static void close(Object...args){
  33. try {
  34. if(args.length == 3 && args[2] != null){
  35. ResultSet rs = (ResultSet) args[2];
  36. rs.close();
  37. }
  38. if(args[1] != null){
  39. PreparedStatement ps = (PreparedStatement) args[1];
  40. ps.close();
  41. }
  42. if(args[0] != null){
  43. Connection conn = (Connection)args[0];
  44. conn.close();
  45. }
  46. }catch (Exception e){
  47. e.printStackTrace();
  48. }
  49. }
  50. }

三、拓展

3.1、单元测试junit

测试分为白盒和黑盒测试

黑盒:关注的是结果

百盒: 关注的是过程(会对每一句代码进行测试)—需要技术要求

junit属于白盒测试的一种,需要提供第三方jar包

步骤

  1. 1 引入jar
  2. 2 写一个测试类(XxxTest),严禁取名叫Test
  3. 3 写测试方法(TestXxx) ,严禁取名叫Test
  4. 4 选中要测试的方法名,右键run as --- junit test
  5. 4.5 如果要测所有方法,直接再空白处右键run as --- junit test
  6. 5 运行后:
  7. 绿色:正确无误
  8. 红色:有错误
  9. 注意:测试用的方法的权限修饰符必须是public
  10. 注意:测试方法没有返回值和形参

@Before @After

  1. 语法:
  2. @Before
  3. public void 方法名(){} 能够再@Test方法之前执行
  4. @After
  5. public void 方法名(){} 能够再@Test方法之后执行

3.2、断言

语法:

Assert.assertEquals(期望值,真实值);判断两个值是否相等,如果不相等,报错

  1. @Test
  2. public void testAdd(){
  3. User u=new User();
  4. int sum=u.add(1, 2);
  5. Assert.assertEquals(4, sum);
  6. }

3.3、三种方式获取properties文件的数据

方式1:ResourceBundle

我们需要把properties文件放在src下,相对于src

  1. 如果是放在src下的xx包中:
  2. ResourceBundle.getBundle("xx/db");
  3. ResourceBundle.getBundle("xx.db");
  1. ResourceBundle rb = ResourceBundle.getBundle("db");
  2. String root = rb.getString("user");
  3. System.out.println(root);

方式2: 通过流+properties对象

properties文件放在项目根目录,相对与项目根目录

如果是直接放在根目录:db.properties

如果是放在根目录下的xx文件夹:xx/db.properties

如果是放在src: src/db.properties

  1. FileReader fr=new FileReader(new File("db.properties"));
  2. // FileInputStream fis=new FileInputStream(new File("db.properties"));
  3. //集合
  4. Properties pro=new Properties();
  5. pro.load(fr);
  6. System.out.println(pro.getProperty("user"));
  7. System.out.println(pro.getProperty("password"));

方式3: 通过类加载器搭配properties

  1. //通过某个类的类加载器去读取流
  2. InputStream in = Demo3.class.getClassLoader().getResourceAsStream("db.properties");
  3. //集合
  4. Properties pro=new Properties();
  5. pro.load(in);
  6. System.out.println(pro.getProperty("user"));
  7. System.out.println(pro.getProperty("password"));