一、xml
1.简介 2.特点 3.使用步骤
二、Reflect反射
1.概念 2.理解Class类 3.反射的功能 4.两个案例
一、xml
1.简介
xml是一种可扩展标记语言,简称XML。可用来存储和传输数据。
例如:
<families>
<family>
<person>
<name>父亲1</name>
<age>36</age>
</person>
<person>
<name>母亲1</name>
<age>35</age>
</person>
</family>
<family>
<person>
<name>父亲2</name>
<age>34</age>
</person>
<person>
<name>母亲2</name>
<age>33</age>
</person>
</family>
</families>
2.特点
- 需导入两个相关jar包:dom4j-1.6.1.jar和jaxen-1.1.1.jar
- 必须要有一个根标签
- 任意标签之间只能包含或并列,合理嵌套
3.使用步骤
// 1.导入两个相关jar包
// 2.创建sax解析器对象
SAXReader reader = new SAXReader();
// 3.读取某个xml文件,返回一个文档对象
Document doc = reader.read("src/xml1/a.xml");
// 4.由文档对象获取根标签
Element root = doc.getRootElement();
// 5.使用 .elements()/.element() 方法逐级向下寻找标签
Element family1 = (Element) root.elements("family").get(0);
Element person1 = (Element)family1.elements("person").get(0);
Element age = person1.element("age");
System.out.println(age.getText());//获取标签的文本内容
System.out.println(age.getName());//获取标签名
二、Reflect反射
1.概念
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2.理解Class类
基于Java中面向对象的概念,所有字节码文件也可以是一个类,这个类就是Class类,它可以管理某个类的无参/有参构造,属性和方法。
3.反射的功能
(1)三种方法获取Class对象
- 通过类名
Class c1 = Dog.class;
- 通过对象
Class c2 = new Dog().getClass();
- 通过类路径
Class c3 = Class.forName("Task.Book");
(2)获取和调用构造方法
①获取所有构造方法:
// 获取所有的构造方法(包括:私有、受保护、默认、公有)
Constructor[] conArray = clazz.getDeclaredConstructors();
②获取所有公有构造方法:
// 获取所有公有构造方法
Constructor[] conArray = clazz.getConstructors();
③获取并调用公有、无参的构造方法:
// 获取并调用公有、无参的构造方法
Constructor con = clazz.getConstructor(null);// null可以不写
Object obj = con.newInstance();
④获取并调用私有的构造方法:
// 获取并调用私有的构造方法
Constructor con = clazz.getDeclaredConstructor(String.class);
con.setAccessible(true);//暴力反射
Object obj = con.newInstance("张三");
(3)获取并调用成员变量
①获取所有属性:
// 获取所有属性(包括:私有、受保护、默认的)
Field[] fieldArray = clazz.getDeclaredFields();
for(Field f : fieldArray){
System.out.println(f);
}
②获取所有公有的属性:
// 获取所有公有的属性
Field[] fieldArray = clazz.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
③获取并调用公有的XX属性:
// 获取并调用公有的XX属性
Field f = clazz.getField("name");
f.set(obj, "张三");
④获取并调用私有的XX属性:
// 获取并调用私有的XX属性
Field f = clazz.getDeclaredField("age");
f.set(obj, 18);
(4)获取和调用成员方法
①获取所有成员方法
// 获取所有成员方法(包括:私有的)
Method[] methodArray = clazz.getDeclaredMethods();
②获取所有公有成员方法:
// 获取所有公有成员方法
Method[] methodArray = clazz.getMethods();
③获取并调用公有的XX成员方法:
// 获取并调用公有的XX成员方法
Method m = clazz.getMethod("setName", String.class);
m.invoke(obj, "张三");
④获取并调用私有的XX成员方法:
// 获取并调用私有的XX成员方法
Method m = clazz.getDeclaredMethod("setAge", int.class);
m.setAccessible(true);// 暴力反射
m.invoke(obj, 18);
(5)获取和调用main方法
①获取main方法:
Method methodMain = clazz.getMethod("main", String[].class);
②调用main方法:
methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一
methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
4.扩展:两个案例
(1)反射结合泛型
将一个map中的数据转存到一个实体类对象中。
@Test
public void test5() throws Exception {
HashMap<String, Object> map = new HashMap<>();
map.put("name","旺财");
map.put("age",3);
Dog dog = getObject(map, Dog.class);
System.out.println(dog);
}
public <T>T getObject(Map<String,Object> map, Class<T> c) throws Exception {
T t = c.newInstance();
//1.拆开map
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> entry : entries) {
String key = entry.getKey();
//2.将map中的值存入T这个类的对象属性中
Field f = c.getDeclaredField(key);
f.setAccessible(true);
f.set(t,entry.getValue());
}
return t;
}
(2)反射结合xml
预先定义好父类:动物类,子类:狗狗类,企鹅类,大象类,
在xml文件中配置各个宠物类的全路径名
编写一个宠物领养方法,根据用户输入的宠物名称,从xml读取相应的类路径,使用反射构建宠物对象,并返回。
注意:使用父类作为方法返回值,字符串作为参数。
<?xml version="1.0" encoding="UTF-8" ?>
<animal>
<狗狗>
<name>旺财</name>
<class>reflect.pet.Dog</class>
</狗狗>
<企鹅>
<name>皮皮</name>
<class>reflect.pet.Penguin</class>
</企鹅>
<大象>
<name>肉肉</name>
<class>reflect.pet.Elephant</class>
</大象>
</animal>
@Test
public void test1() throws Exception {
Scanner sc=new Scanner(System.in);
System.out.println("请选择您要领养的宠物:狗狗,企鹅,大象");
String name = sc.next();
Animal animal = getAnimal(name);
System.out.println(animal);
}
public Animal getAnimal(String name) throws Exception {
// 1.创建解析器
SAXReader reader = new SAXReader();
// 解析xml文档,得到document对象
Document document = reader.read("src/reflect1/pet/pet.xml");
// 根据document对象获取根节点
Element root = document.getRootElement();
// 查找根节点下的子节点 element() elements()
Element animal = root.element(name);
String className = animal.element("class").getText();
//2.使用反射创建对象
return (Animal) Class.forName(className).newInstance();
}