Xml和反射
1.xml简介
可扩展标记语言
,简称XML
。是一种用于标记电子文件使其具有结构性的标记语言
。 在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。早在1998年,W3C就发布了XML1.0规范,使用它来简化Internet的文档信息传输。
- 存储数据
- 传输数据
<?xml version="1.0" encoding="UTF-8"?>
<msgs>
<msg>
<time>2021-07-14 11:35:22</time>
<sender>1832444366</sender>
<reveiver>1234567891</reveiver>
<content>哈哈哈哈</content>
</msg>
<msg>
<time>2021-07-14 11:50:22</time>
<sender>1234567891</sender>
<reveiver>1832444366</reveiver>
<content>啦啦啦</content>
</msg>
</msgs>
- 总结特点
1.必须要有一个跟标签
2.任意标签之间只能是包含关系或并列关系,合理的嵌套
3.除了标签体,还可以有属性和文本。
4.xml中没有内置任何标签,没有内置任何属性。所以:标签和属性都是自定义的。
2.xml解析
- 解析方式
DOM(Document Object Model)解析:是基于 XML 文档树结构的解析,整颗树加载到内存中,耗内存,可多次获取。
SAX(Simple API for XML)解析:是基于事件流的解析。效率高,数据量小,仅一次获取 。
DOM4J解析
:融合了Dom和Sax的优点,即能保证效率,同时也可多次获取
。著名的开发框架Spring和Hibernate都使用了Dom4j的功能。.
2.1查询
- 先导入jar包: dom4j-1.6.1.jar
SAXReader: 读取文件的解析器
Document : 文档树
Element : 元素–标签
@Test //查询
public void test1() throws Exception {
//1.创建解析器
SAXReader saxReader = new SAXReader();
//2.读取某个xml文件,返回xml对应的dom文档树
Document doc = saxReader.read("src/xml/msg.xml");
//3.获取根标签
Element root = doc.getRootElement();
System.out.println(root.getName());
//4.1 获取所有子标签
List<Element> msgs = root.elements();
for (Element msg : msgs) {
System.out.println(msg.getName());
}
//4.1获取第一个子标签
Element e = msgs.get(0);
System.out.println(e.getName());
Element ee = root.element("msg");
System.out.println(ee.getName());
//4.2使用迭代器获取子标签
Iterator it = e.elementIterator();
while (it.hasNext()){
Element e1 = (Element) it.next();
System.out.println(e1.getName()+"---"+e1.getText());
}
}
2.2增删改
-
文档对象的来源
- 文档对象可以是通过
SaxReader获取到的
- 也可以是
DocumentHelper.createDocument();
- 文档对象可以是通过
-
增删改操作都需要将文档对象重新写入xml文件
,用更新后的dom去覆盖之前的dom树
@Test //新增
public void test2() throws Exception{
//一、构建文档树
//1.创建解析器
SAXReader saxReader = new SAXReader();
//2.读取某个xml文件,返回xml对应的dom文档树
Document doc = saxReader.read("src/xml/msg.xml");
//3.获取根标签
Element root = doc.getRootElement();
//4.给根标签加子标签
Element msg3 = root.addElement("msg3");
Element content = msg3.addElement("content");
content.addText("今天真好啊");
//二、用新的文档树覆盖旧的文档树
//1.借助字节输出流
FileOutputStream out = new FileOutputStream("src/xml/msg.xml");
//2.需要格式美化对象
OutputFormat format = OutputFormat.createPrettyPrint();
//3.根据上面两个对象 构建一个xml输出流对象
XMLWriter xmlWriter = new XMLWriter(out,format);
//4.将doc 文档树重新写入xml文件
xmlWriter.write(doc);
//5.关闭流---刷新缓冲区
xmlWriter.close();
}
@Test //新增---2
public void test3() throws Exception {
//1.自己创建一个文档对象
Document doc = DocumentHelper.createDocument();
//2.添加根元素
Element root = doc.addElement("CHINA");
//3.添加子元素
Element shandong = root.addElement("SHANDONG");
Element name = shandong.addElement("NAME");
Element age = shandong.addElement("AGE");
//给子元素设置文本
name.setText("泰安");
age.setText("666888");
//将上面创建的dom树 写进一个xml文件中 创建新的CHINA.xml文件
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/xml/CHINA.xml"), OutputFormat.createPrettyPrint());
xmlWriter.write(doc);
}
1.反射概念
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
理解Reflect
- 反射
- 反转
理解为控制反转,权力的反转:每一个人都有活着的权力,行动和自由的权力;每一个类都有创建对象,调用属性和方法的权力。现在将类的这些权力转交给Class对象,让它来帮助某个类去完成这些操作。
- 理解Class
每一个实体类都会被编译成字节码文件,java眼中万事万物都是对象,那么天下所有的字节码文件都可以看成是对象,谁的对象呢? 当然得有一个类,来代表所有的字节码文件,这个类就是Class类。
即:所有类文件被编译成字节码文件后,都可以看成是Class类的对象。
例如:
Class c=Dog.class; //Dog.class就表示Dog类文件被编译后的字节码文件
2.反射功能
- 三种方式获取Class对象
@Test //任意一个类 获取class对象
public void test1() throws Exception{
//1.类名.class
Class<Hero> heroClass = Hero.class;//代指Hero.java被编译后的字节码文件
//2.对象的getClass方法
Class<? extends Hero> c2 = new Hero().getClass();
//3.Class的静态方法forName
Class<?> c3 = Class.forName("reflect.Hero");
}
- Class对象操作普通类------普通方法
@Test //Class对象操作普通类------普通方法
public void test3() throws Exception {
//1.类名.class 得到class对象
Class<Hero> heroClass = Hero.class;//代指Hero.java被编译后的字节码文件
//管理toString方法----获取toString方法管理对象
Method m1 = heroClass.getDeclaredMethod("toString");
//调用方法
System.out.println(m1.invoke(heroClass.newInstance()));
//获取setName方法管理对象
Method m2 = heroClass.getDeclaredMethod("setName", String.class);
Hero h = heroClass.newInstance();
m2.invoke(h,"老婆");
System.out.println(h);
}
- Class对象操作普通类------构造方法
@Test //Class对象操作普通类------构造方法
public void test2() throws Exception {
//1.类名.class
Class<Hero> heroClass = Hero.class;//代指Hero.java被编译后的字节码文件
//2.操作Hero类的无参构造
Hero hero = heroClass.newInstance();
System.out.println(hero);
//3.操作Hero的有参构造----获取Constructor类
Constructor<Hero> con = heroClass.getDeclaredConstructor(String.class,int.class);
System.out.println(con.newInstance("哈哈", 98));
//4.获素有的构造方法
Constructor<?>[] cons = heroClass.getDeclaredConstructors();
for (Constructor<?> c : cons) {
System.out.println(c);
System.out.println(c.getParameterCount());
Class<?>[] c1 = c.getParameterTypes();
for (Class<?> cc : c1) {
System.out.println(cc.getName());
}
}
}
- Class对象操作普通类------管理属性
@Test //Class对象操作普通类------属性
public void tes4() throws Exception {
//1.类名.class 得到class对象
Class<Hero> heroClass = Hero.class;//代指Hero.java被编译后的字节码文件
//2.获取某个属性的管理对象
Field f = heroClass.getDeclaredField("name");
//3.给name属性赋值
Hero h = heroClass.newInstance();
//暴力反射 开启私有属性的操作权限
f.setAccessible(true);
f.set(h,"老婆");
System.out.println(h);
//3.2给age属性赋值
Field f1 = heroClass.getDeclaredField("age");
f1.setAccessible(true);
f1.set(h,18);
System.out.println(h);
}