小汤学编程之JAVA基础day14——xml和反射

本文介绍了XML的基本概念、特点和使用步骤,详细阐述了JAVA反射机制,包括Class类的理解、反射的主要功能,并通过实例展示了如何获取和调用构造方法、成员变量和方法。此外,还探讨了反射在泛型和XML解析中的应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

一、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();
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值