反射 注解 XML总结
Posted 夏芷雨涵梦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射 注解 XML总结相关的知识,希望对你有一定的参考价值。
反射 注解 XML
时间:2019.08.16 作者:夏晓林 内容:反射注解和xml
反射技术的操作:
获取类的对象:
- 使用class属性:Person.class
- 使用getClass()方法:person.getClass()
- 使用Class.forName():括号里是完整的包名和类名。
//方式1:使用class属性
Class<Demo1> demo1Class = Demo1.class;
System.out.println(demo1Class.hashCode());
//方式2:使用getClass方法
Demo1 demo1=new Demo1();
Class<?> aClass = demo1.getClass();
System.out.println(aClass.hashCode());
//方式3 使用Class.forName方法:耦合性低,依赖类的全名称,即使没有类也能编译通过
Class<?> aClass1 = Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
System.out.println(aClass1.hashCode());
使用第三种方式,因为该方式可以在没有类的情况下进行编译而不会报错,耦合性低
扩展知识:获取父类、接口、包名
//获取父类
Class<?> superclass = aClass1.getSuperclass();
System.out.println(superclass.getName());//获取父类的名字
Type type = aClass1.getGenericSuperclass();//获取带泛型的类
System.out.println(type.getTypeName());
//获取接口
Class<?>[] interfaces = aClass1.getInterfaces();
System.out.println(interfaces.length);
//获取包名
Package aPackage = aClass1.getPackage();
System.out.println(aPackage.toString());
获取类中的构造方法:
包括获取无参的和有参数的,利用构造方法创建对象
//获取构造方法
Class<?> clazz=Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors)
System.out.println(constructor);
//获取单个构造方法
//无参数的构造方法
Constructor<?> constructor = clazz.getConstructor();
//获取带参数的
Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class);
System.out.println(constructor1);
//利用构造方法创建对象
Object lisi = constructor.newInstance();
System.out.println(lisi);
Object xiayu = constructor1.newInstance("夏雨", 10, "男");
System.out.println(xiayu.toString());
Object o = clazz.newInstance();
System.out.println(o.toString());
获取方法:
获取无参数的、有参的、静态的、有返回值的、私有的(要将访问权限设置为无效,setAccessible(true))
public static void getMethod() throws Exception
//获取无参的方法
Class<?> clazz = Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
//Method[] methods = clazz.getMethods();//公开的方法,还有继承的公开方法
/* Method[] methods = clazz.getDeclaredMethods();//获取类自己的所有方法,包括非公开的
System.out.println("-----Method----");
for (Method method : methods)
System.out.println(method);
*/
Object zhangsan = clazz.newInstance();
Method show = clazz.getMethod("show");
show.invoke(zhangsan);
//获取有参的方法
Method show1 = clazz.getMethod("show",String.class);
show1.invoke(zhangsan,"北京");
//带返回值的方法
Method getInfo = clazz.getMethod("getInfo");
Object invoke = getInfo.invoke(zhangsan);
System.out.println(invoke);
//静态方法
Method pring = clazz.getMethod("pring");
pring.invoke(null);
//私有方法
Method show2 = clazz.getDeclaredMethod("show", String.class, String.class);
//去掉修饰符,设置访问权限无效
show2.setAccessible(true);
show2.invoke(zhangsan,"北京","2342343@qq.com");
获取类的属性(一般不建议使用,违反了封装的特性,框架中会使用)
public static void getField() throws Exception
//获取类对象
Class<?> clazz = Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
Object lisi = clazz.newInstance();
//获取
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields)
System.out.println(declaredField);
//获取单个
Field name = clazz.getDeclaredField("name");
//赋值
name.setAccessible(true);
name.set(lisi, "李四");
//获取
Object o = name.get(lisi);
System.out.println(o);
注解:
注解中的属性类型:
- String类型
- 基本类型
- class类型
- 枚举类型
- 注解类型
- 或者以上类型的一维数组
注解其实就是接口,编译后就是将@符号去掉,将属性变为接口的抽象方法
在一个注解中,如果只有一个属性并且名字为value,那么在调用的时候可以不用写value,如果不是该名字或者是多个属性的话,必须全写
元注解:修饰注解的注解
@Retention:修饰注解的存活时间,默认class是在编译的时候存在,运行的时候消失;runtime是一直存在,source是只在代码中体现,编译的时候就没有了
RetentionPolicy.CLASS: 编译器将把注解记录在 class文件中. 当运行 Java 程序时, JVM 不会保留注解. 这是默认值
RetentionPolicy.RUNTIME:编译器将把注解记录在 class文件中. 当运行 Java 程序时, JVM 会保留注解. 程序可以通过反射获取该注释
RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释
@Inherited:是指该注解能够继承,子类可以获取到父类上的注解
@Target:指定注解用于修饰类的那个成员,@target包含了一个名字为value。类型为ElementType的成员变量。
@Documented:用于指定被该元 Annotation 修饰的Annotation类将被 javadoc 工具提取成文档。
XML语言
为什么使用xml语言
- 问题1:Windows系统的应用怎么和Linux系统中的应用交互数据
- 问题2:其他诸如此类跨平台、跨操作系统的数据交互问题
xml的概述
可扩展性标记语言(eXtensible Markup Lanauage),文件扩展名为.xml
用途:描述、传输数据
使用场合:
- 持久化存储数据
- 数据交换
- 数据配置
xml语法
文档声明
在编写XML文档时,需要先使用文档声明,声明XML文档的类型。
最简单的声明语法:
<?xml version="1.0" ?>
用encoding属性说明文档的字符编码:
<?xml version="1.0" encoding="GBK" ?>
元素
XML元素指XML文件中出现的标签,一个标签分为开始标签和结束标签,一个标签有如下几种书写形式,例如:
包含标签体:<a>www.qianfeng.cn</a>
不含标签体的:<a></a>, 简写为:<a/>
一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套 ,例如:
<a>welcome to <b>www.qianfeng.org</a></b>
格式良好的XML文档必须有且仅有一个根标签,其它标签都是这个根标签的子孙标签。
对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。
<Name>
冰冰
</Name>
和
<Name>冰冰</Name>
一个XML元素可以包含字母、数字以及其它一些可见字符,但必须遵守下面的一些规范:
1名称可以含字母、数字以及其他的字符
2名称不能以数字或者标点符号开始
3名称不能以字符 “xml”(或者 XML、Xml)开始
4名称不能包含空格
使用浏览器验证文件格式有效性。
属性
一个标签可以有多个属性,每个属性都有它自己的名称和取值,例如:
<Student name="zhangsan">
属性值一定要用双引号(")或单引号(')引起来
定义属性必须遵循与标签相同的命名规范
在XML技术中,标签属性所代表的信息,也可以被改成用子元素的形式来描述,例如:
<Student>
<name>text</name>
</Student>
注释
Xml文件中的注释采用:“<!--注释-->” 格式。
注意:
1 XML声明之前不能有注释
2 注释不能嵌套
格式良好的XML文档
1必须有XML声明语句
2必须有且仅有一个根元素
3标签大小写敏感
4属性值用双引号或单引号
5标签成对
6元素正确嵌套
XMl解析
XML解析方式
◦1 DOM解析
使用DOM4J(DOM For Java)实现DOM解析
Java: JAXP技术
◦2 SAX解析(了解即可)
Pull解析和Sax类似
DOM和SAX比较
DOM解析 (Document Object Model) 文档对象模型
易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。
效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用
支持增删改查
SAX解析(Simple API for Xml)
SAX是一个用于处理XML事件驱动的“推”模型,虽然它不是W3C标准,但它却是一个得到了广泛认可的API
SAX模型最大的优点是内存消耗小
只适合读取
6.1使用DOM4J解析
Dom for java
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
使用Dom4j开发,需下载Dom4j相应的jar文件
项目中如何使用DOM4J
(1)项目中创建文件夹lib
(2)把jar包复制到lib目录中
(3)右击jar包--->Add as library--->进行选择
如果第二次带入jar包,不能正常运行,此时不要再执行以上操作,直接关闭项目再打开即可
获取Document对象
SAXReader reader = new SAXReader();
Document document= reader.read(new File("input.xml"));
节点对象操作
1.获取文档的根节点.
Element root = document.getRootElement();
2.取得某个节点的子节点.
Element element=node.element(“书名");
3.取得节点的文字
String text=node.getText();
4.取得某节点下所有名为“member”的子节点,并进行遍历.
List nodes = rootElm.elements(“book");
for (Iterator it = nodes.iterator(); it.hasNext();)
Element elm = (Element) it.next();
do something
节点属性操作
1.取得某节点下的某属性
Element root=document.getRootElement();
//属性名name
Attribute attribute=root.attribute("size");
2.取得属性的文字
String text=attribute.getText();
3.删除某属性
Attribute attribute=root.attribute("size");
root.remove(attribute);
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
/*
* created by 夏晓林 in 2019/8/16/016 at 10:01
* 使用反射技术操作
* 1.获取类的对象
* 2.获取类中的构造方法
* 3.获取方法
*
*/
public class ReflectDemo1
public static void main(String[] args)throws Exception
//getClazz();
//getConstructor();
//getMethod();
getField();
//获取类的对象
public static void getClazz() throws Exception
//方式1:使用class属性
Class<Demo1> demo1Class = Demo1.class;
System.out.println(demo1Class.hashCode());
//方式2:使用getClass方法
Demo1 demo1=new Demo1();
Class<?> aClass = demo1.getClass();
System.out.println(aClass.hashCode());
//方式3 使用Class.forName方法:耦合性低,依赖类的全名称,即使没有类也能编译通过
Class<?> aClass1 = Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
System.out.println(aClass1.hashCode());
//扩展知识
//获取父类
Class<?> superclass = aClass1.getSuperclass();
System.out.println(superclass.getName());//获取父类的名字
Type type = aClass1.getGenericSuperclass();//获取带泛型的类
System.out.println(type.getTypeName());
//获取接口
Class<?>[] interfaces = aClass1.getInterfaces();
System.out.println(interfaces.length);
//获取包名
Package aPackage = aClass1.getPackage();
System.out.println(aPackage.toString());
public static void getConstructor() throws Exception
//获取构造方法
Class<?> clazz=Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors)
System.out.println(constructor);
//获取单个构造方法
//无参数的构造方法
Constructor<?> constructor = clazz.getConstructor();
//获取带参数的
Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class);
System.out.println(constructor1);
//利用构造方法创建对象
Object lisi = constructor.newInstance();
System.out.println(lisi);
Object xiayu = constructor1.newInstance("夏雨", 10, "男");
System.out.println(xiayu.toString());
Object o = clazz.newInstance();
System.out.println(o.toString());
public static void getMethod() throws Exception
//获取无参的方法
Class<?> clazz = Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
//Method[] methods = clazz.getMethods();//公开的方法,还有继承的公开方法
/* Method[] methods = clazz.getDeclaredMethods();//获取类自己的所有方法,包括非公开的
System.out.println("-----Method----");
for (Method method : methods)
System.out.println(method);
*/
Object zhangsan = clazz.newInstance();
Method show = clazz.getMethod("show");
show.invoke(zhangsan);
//获取有参的方法
Method show1 = clazz.getMethod("show",String.class);
show1.invoke(zhangsan,"北京");
//带返回值的方法
Method getInfo = clazz.getMethod("getInfo");
Object invoke = getInfo.invoke(zhangsan);
System.out.println(invoke);
//静态方法
Method pring = clazz.getMethod("pring");
pring.invoke(null);
//私有方法
Method show2 = clazz.getDeclaredMethod("show", String.class, String.class);
//去掉修饰符,设置访问权限无效
show2.setAccessible(true);
show2.invoke(zhangsan,"北京","2342343@qq.com");
public static void getField() throws Exception
//获取类对象
Class<?> clazz = Class.forName("com.qf1.fourth0816.reflectDemo.Demo1");
Object lisi = clazz.newInstance();
//获取
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields)
System.out.println(declaredField);
//获取单个
Field name = clazz.getDeclaredField("name");
//赋值
name.setAccessible(true);
name.set(lisi, "李四");
//获取
Object o = name.get(lisi);
System.out.println(o);
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;
/*
* created by 夏晓林 in 2019/8/16/016 at 16:46
* 注意BOM头的问题,如果直接从记事本中复制到目录中,会出现前沿不允许有内容的错误
* 解决方法:直接写内容
*/
public class Demo2
public static void main(String[] args) throws Exception
//readXML();
//writexml();
//updateAndDelete();
readXMLXPath();
//读取文件
public static void readXML() throws Exception
//1.创建一个SaxReader读取器(类似流)
SAXReader reader =new SAXReader();
//2.读取,返回Document对象代表DOM树
Document document=reader.read(new FileReader("books.xml"));以上是关于反射 注解 XML总结的主要内容,如果未能解决你的问题,请参考以下文章
Java反射学习总结五(Annotation(注解)-基础篇)