Java复习-反射与配置文件解析

本文详细介绍了Java中的反射机制,包括类的加载、类加载器的分类和作用,以及如何通过反射访问类的方法和属性。此外,还讲解了配置文件解析,特别是对properties和XML文件的处理,利用dom4j库进行解析和生成XML文件的操作。
摘要由CSDN通过智能技术生成

七 JAVA反射
7.1类的加载概述和加载时机
A:类的加载概述
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
1)加载
就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。
2)连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化 就是我们以前讲过的初始化步骤
B:加载时机
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
7.2类加载器的概述和分类
A:类加载器的概述
负责将.class文件加载到内存中,并为之生成对应的Class对象。虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。

B:类加载器的分类
Bootstrap ClassLoader 根类加载器
Extension ClassLoader 扩展类加载器
Sysetm ClassLoader 系统类加载器

C:类加载器的作用
Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
7.3反射概述
Java反射机制:XxxYyy.class -->XxxYyy.java(框架)
1)JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
2)对于任意一个对象,都能够调用它的任意一个方法和属性;
3)这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
4)要想解剖一个类,必须先要获取到该类的字节码文件对象。
5)而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象。
Java反编译技术:基于Java反射机制的实现
反编译工具/逆向工程工具

  1. 反射是Java自我管理的机制

  2. 可以通过反射机制发现对象的类型 发现类型的方法/属性/构造器

  3. Java 反射 访问任意对象方法和属性等

  4. Class 加载
    类加载到内存: java 将磁盘类文件加载到内存中,为一个对象(实例)
    这个对象是Class的实例, 也就是 这些对象都是Class实例
    5)Class 实例获得
    Class cls = String.class;
    Class cls = Class.forName(“java.lang.String”);
    Class cls = “abc”.getClass();

    获取字节码对象的三种方式,返回的字节码对象都是唯一的

7.4 反射案例
1发现类的方法,属性,构造方法
1)首先获取字节码对象 2):通过字节码对象获取全部的属性方法等
public void call(Object obj){
Class<?> cla=obj.getClass();

	System.out.println("----------------------->输出所有的属性");
	Field[] fields = cla.getDeclaredFields();
	StringBuilder sb=new StringBuilder();
	for (Field field:fields) {
		sb.append(Modifier.toString(field.getModifiers())+" ");
		sb.append(subStrings(field.getType())+" ");
		sb.append(field.getName()+"\n");
		
	}
	System.out.println(sb);
	
	System.out.println("----------------------->输出所有的构造方法");
	Constructor<?>[] constructors = cla.getDeclaredConstructors();
	StringBuilder sb2=new StringBuilder();
	for (Constructor<?> c : constructors) {
		sb2.append(Modifier.toString(c.getModifiers())+" ");
		sb2.append(subStrings(cla)+" (");
		Class<?>[] type = c.getParameterTypes();
		for (Class<?> typeVariable : type) {
			sb2.append(subStrings(typeVariable)+",");
		}
		if(type.length!=0){
			sb2.deleteCharAt(sb2.length()-1);
		}
		sb2.append("){} \n");
	}
	System.out.println(sb2);
	
	System.out.println("----------------------->输出所有的方法");
	Method[] methods = cla.getDeclaredMethods();
	StringBuilder sb3=new StringBuilder();
	for (Method method : methods) {
		sb3.append(Modifier.toString(method.getModifiers())+" ");
		sb3.append(subStrings(method.getReturnType())+" ");
		sb3.append(method.getName()+"(");
		Class<?>[] types = method.getParameterTypes();
		for (Class<?> class1 : types) {
			sb3.append(subStrings(class1)+",");
		}
		if(types.length!=0){
			sb3.deleteCharAt(sb3.length()-1);
		}
		sb3.append("){} \n");
		
	}
	System.out.println(sb3);
}

//字符串截取
public String subStrings(Class<?> type){
	String str=type.toString();
	return str.substring(str.lastIndexOf(".")+1);
	
}

2调用类的属性,方法,构造方法
public void result(Object object){
System.out.println("----------------------->调用类的属性");
Class<?> cla=object.getClass();
Field field = cla.getDeclaredField(“type”);
field.set(object, “拉布拉多”);
Field field2 = cla.getDeclaredField(“age”);
field2.setAccessible(true);
field2.set(object, 5);
Field field3 = cla.getDeclaredField(“name”);
field3.set(object, “九月”);
System.out.println(object);

	 System.out.println("----------------------->调用类的构造方法");
	 Class<?>[] parameterTypes={String.class,int.class,String.class};
	 Constructor<?> constructor = cla.getDeclaredConstructor(parameterTypes);
	 Object newInstance = constructor.newInstance(new Object[]{"十月",10,"泰迪"});
	 System.out.println(newInstance);
	 
	 System.out.println("----------------------->调用类的方法");
	 Class<?>[] types={String.class,int.class};
	 Method method = cla.getDeclaredMethod("print", types);
	 Object []agrs ={"泰迪",5};
	 System.out.println(method.invoke(object,agrs ));
}

八JAVA配置文件解析
8.1 配置文件类型properties与xml
properties属性文件:简单的数据源,只能是字母和数字
文件后缀名必须是xxx.properties
工具类ConfigUtils:专门用来加载属性文件

    xml文件:框架使用
 8.2配置文件对比
    1、从结构上来说: 
            .xml文件主要是树形结构。
            .properties文件主要是以key-value键值对的形式存在。

    2、从灵活程度上来说:
           .xml格式的文件要比.properties格式的文件更灵活一些
           .properties格式的文件已键值对形式存在,主要就是赋值,而且只能赋值,不能够进行其他的操作。
           .xml格式的文件可以有多种操作方法,例如添加一个属性,或者做一些其他的定义等。

    3、从使用便捷程度来说:  
          .properties格式的文件要比.xml文件配置起来简单一些。
            配置.properties只需要简单的getProperty(key)方法或者setProperty(key,value)方法就可以读取或者写入内容;
          .配置.xml文件的时候通常要查看文档,因为配置比较繁琐,花费时间长才可以配置完整。

   4、从应用程度上来说:
         .properties文件比较适合于小型简单的项目。
         .xml文件适合大型复杂的项目,因为它比较灵活。
8.3文件解析

1)Java里面的配置文件解析
properties文件:属性文件

  2)xml文件:
           DOM解析,SAX解析(Java基础解析方式)
           DOM4J解析:扩展解析,Java里面使用频繁
           PULL解析:扩展解析,Android SDK自带的解析方法

  3)dom4j:dom for Java
           第三方的Jar,必须引入到工程里面
           项目根目录新建文件夹lib,复制dom4j.Jar包到lib,右键Build path,添加到项目

4)dom4j解析xml文件
1.获取SAXReader解析器
2.调用sax.read(is)方法返回Document对象
3.调用Document的getRootElement()方法返回根元素Element
4.调用Element的elements(“new”)返回List集合
5.遍历List集合获取属性值和元素值
List arrList=ele.attributes():获取属性值
ele.elementText(“title”):获取元素值

5)dom4j生成xml文件
1.通过DocumentHelper创建空xml文档对象Document
2.通过Document的addElement(“news”)方法添加节点元素Element
3.通过循环向节点添加数据
4.XMLWriter writer=new XMLWriter(os);

参考代码:
/**dom4j解析xml文件:工具类 */
public class Dom4jParseXmlUtils {
/**dom4j解析xml文件
* @param is 输入流
* @return
*/
public static List parse(InputStream is){
List lists=new ArrayList();
//1.获取SAXReader解析器
SAXReader sax=new SAXReader();
//调用sax.read(is)方法返回Document对象
try {
Document doc=sax.read(is);
//3.调用Document的getRootElement()方法返回根元素Element
Element rootEle=doc.getRootElement();
//4.通过根元素rootEle获取指定子元素
List eles = rootEle.elements(“new”);
//5.循环遍历每个Element,获取数据,封装到New对象
for (Element ele : eles) {
New newInfo=new New();
//获取元素的内容
String title=ele.elementText(“title”);
newInfo.setTitle(title);
String detail=ele.elementText(“detail”);
newInfo.setDetail(detail);
String comment=ele.elementText(“comment”);
newInfo.setComment(Long.parseLong(comment));//“89899”–>89899
String image=ele.elementText(“image”);
newInfo.setImage(image);
lists.add(newInfo);
}
return lists;
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值