反射和XML

反射

1.反射机制:
Java的反射机制是指在运行状态中,对于任何一个类,都可以知道这个类所有属性和方法,对于任何一个对象,都可以用这个对象调用所有方法和属性,这种动态获取数据和操作对象的方法和属性的能力叫反射机制.

2.反射:
将java类中所有成员属性,方法,构造方法映射成一个个对象.
反射是所有框架的灵魂.
属性->映射成->Field的对象
方法->映射成->Method的对象
构造方法->映射成->Constructor的对象

3.反射对象:
当程序运行,第一次加载类时,先将硬盘上.class文件加载内存中,这时类加载器和JVM会根据.class文件生成.class对象,这个对象叫反射对象.一个类只有一个反射对象.

4.获得反射对象:
注意:全限定类名:包名.类名
4.1:类名.class;
4.2:对象.getClass();
4.3:Class.forName(“类的全限定类名”) ;(推荐用)

	eg:public static void main(String[] args) throws ClassNotFoundException {
    //创建学生的实例对象
    Student stu1=new Student();
    Student stu2=new Student();

    //获得这个类的反射对象
    Class stuClass=Class.forName("com.qf.day39.demo1.Student");
    //==左右两边是引用数据,比内存地址.
    //一个类只有一个反射对象
    System.out.println(stu1.getClass()==stu2.getClass());//true
    System.out.println(stu1.getClass()==Student.class);//true
    System.out.println(stu1.getClass()==stuClass);//true
}

5.用反射对象操作类的属性

eg:public static void main(String[] args) throws Exception {
    //获得学生类的反射对象
    Class stuClass=Class.forName("com.qf.day39.demo1.Student");
    //用反射对象获得学生类的实例对象,默认调用学生类的无参构造
    Student stu1= (Student) stuClass.newInstance();

    //用反射对象调用方法得到属性的反射对象
    Field snameFidle=stuClass.getDeclaredField("sname");
    //私有属性修改属性访问权限,这样私有的属性也可以访问了
    snameFidle.setAccessible(true);

    //用属性的反射对象调用方法
    System.out.println("属性的访问修饰符:"+snameFidle.getModifiers());
    System.out.println("属性的数据类型:"+snameFidle.getGenericType());

    //用属性的反射对象给某个实例对象的当前这个属性设值
    snameFidle.set(stu1,"刘本益");//相当于stu1.sname="刘本益"

    System.out.println("学生姓名为:"+snameFidle.get(stu1));//相当于stu1.sname
}

6.用反射对象操作类的方法

eg:public static void main(String[] args) throws Exception {
    //获得学生类的反射对象
    Class stuClass=Class.forName("com.qf.day39.demo1.Student");
    //用反射对象获得学生类的实例对象,默认调用学生类的无参构造
    Student stu1= (Student) stuClass.newInstance();

    //用类的反射对象调用方法得到指定方法的反射对象,第一个参数是方法名,第二个参数是方法参数数据类型
    Method show2Method=stuClass.getDeclaredMethod("show2", String.class);
    //设置私有方法权限
    show2Method.setAccessible(true);
    //用方法反射对象调用方法
    System.out.println("方法的访问修饰符:"+show2Method.getModifiers());
    System.out.println("方法的返回值类型:"+show2Method.getGenericReturnType());
    System.out.println("方法的参数列表的数据类型:"+ Arrays.toString(show2Method.getGenericParameterTypes()));

    //用方法的反射对象调用方法
    show2Method.invoke(stu1,"黄小平");//相当于 stu1.show2("黄小平")
}

7.用反射对象操作类的构造方法

	eg:public static void main(String[] args) throws Exception {
    //获得学生类的反射对象
    Class stuClass=Class.forName("com.qf.day39.demo1.Student");

    //用反射对象获得构造方法反射对象
    Constructor stuConstructor=stuClass.getDeclaredConstructor(String.class);
    //私有构造方法修改访问权限
    stuConstructor.setAccessible(true);
    //用构造方法的反射对象调用方法
    System.out.println("构造方法的访问修改符:"+stuConstructor.getModifiers());
    System.out.println("构造方法的参数列表的数据类型:"+ Arrays.toString(stuConstructor.getGenericParameterTypes()));

    //用构造方法的反射对象来调用构造方法创建实例对象
    Student stu1=(Student) stuConstructor.newInstance("刚哥");
}

XML

1.xml:是一种可扩展的标记语言,它也是由标签组成,不同的是它的标签名可以自定义.
		后缀名:.xml.

2.xml作用:用来传输和存储数据。用来作为配置文件;用来跨平台进行数据交换格式.用来作		为持久文件存数据.
		 注意:xml和html都是标记语言,由标签组成.html专门作为前端页面展示,xml用来					作后台数据传输和存储.

3.xml的组成(了解)
	3.1:xml标签规范:
		3.1.1:XML标签区分大小写.
		3.1.2:XML标签一定要关闭.
			 单标签:<标签名 属性名="属性值"/>
			 双标签:<标签名 属性名1="属性值1" 属性名2="属性值2"></标签名>
		3.1.3:XML文档必须有根元素(根标签)
		3.1.4:XML标签要正确嵌套.eg:<标签名1><标签名2></标签名2></标签名1>
		3.1.5:XML标签名可以自定义,但是要像正常人取名就可以.
		3.1.6:XML标签中换行和空格都会当作标签内容
		
	3.2:文档声明:xml文件的版本,规定文件的字符编码等页面属性。
		<? xml version="1.0" encoding="utf-8" ?>必须写在xml文件的第一句。

	3.3:属性:每个标签名的括号中可以有0到多个属性。xml标签的属性值一定要用引号。
			  在同一个标签中,属性不可以重名。
				<标签名 属性1="值1" 属性2="值2" ></标签名>

	3.4:注释:<!--注释内容 -->。注释不能嵌套。

	3.5:实体引用:一些字符拥有特殊的意义.
		  
			<![CDATA[特殊字符]]>

	3.6:处理指令:用来指挥软件如何解析XML文档。语法:<?  ?>
		eg:<?xml version="1.0" encoding="utf-8" ?>

	3.7:xml约束:规范文件的内容。xml约束的类型:xml Schema ,xml DTD
		eg:<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE students [                   <!--xml根据标签是students-->
<!ELEMENT students (student+)>         <!--xml根据标签students有1到多个student子标签-->
<!ELEMENT student (sname,ssex,sage)>   <!--student标签有sname,ssex,sage子标签,顺序规定好了-->
<!ATTLIST student sid CDATA #REQUIRED>  <!--student标签有sid属性,这个属性是必须有的-->
<!ELEMENT sname (#PCDATA)>              <!--sname标签的内容是文本类型-->
<!ELEMENT ssex (#PCDATA)>               <!--ssex标签的内容是文本类型-->
<!ELEMENT sage (#PCDATA)>               <!--sage标签的内容是文本类型-->
]>

		eg:<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE students [                   <!--xml根据标签是students-->
<!ELEMENT students (student+)>         <!--xml根据标签students有1到多个student子标签-->
<!ELEMENT student (sname,ssex,sage)>   <!--student标签有sname,ssex,sage子标签,顺序规定好了-->
<!ATTLIST student sid CDATA #REQUIRED>  <!--student标签有sid属性,这个属性是必须有的-->
<!ELEMENT sname (#PCDATA)>              <!--sname标签的内容是文本类型-->
<!ELEMENT ssex (#PCDATA)>               <!--ssex标签的内容是文本类型-->
<!ELEMENT sage (#PCDATA)>               <!--sage标签的内容是文本类型-->
]>
<students>
    <student sid="1">
        <sname>赵天慧</sname>
        <ssex></ssex>
        <sage>18</sage>
    </student>
    <student sid="2">
        <sname>刚哥</sname>
        <ssex></ssex>
        <sage>18</sage>
    </student>
    <student sid="3">
        <sname>董超</sname>
        <ssex></ssex>
        <sage>17</sage>
    </student>
    <student sid="4">
        <sname>司永康</sname>
        <ssex></ssex>
        <sage>18</sage>
    </student>
</students>

4.DOM4J解析xml:
	4.1:DOM4J解析xml:用一个流将硬盘上xml内容加载到内存中再通过节点方式解析
		优点:可读性;性能优异、功能强大和极其易使用的特点.
		缺点:耗内存.
		Document 文档类 用于加载指定的文档
		常用方法:
		4.1.1:getRootElement() 获取根节点 Element 标签类,元素
		4.1.2:elements() 获取所有的直接子标签 
		4.1.3:element("子标签名")获取指定的直接子标签 
		 4.1.4:element("子标签名").getText()获取指定标签名称的文本内容
		4.1.5:elementText("标签名") 获取指定标签名称的文本内容 element 获取指定					标签名称的标签对象.
		4.1.6:attribute("属性名")属性节点对象
		4.1.7:attribute("属性名").getText();获得属性值
		 4.1.8:attributeValue("属性名");获得属性值

	4.2:DOM4j使用:导包:
eg:public static void main(String[] args) throws Exception {
    //1.创建dom4j的读取对象
    SAXReader reader=new SAXReader();
    //2.用读取对象将硬盘上xml文件读取内存中,用文档对象接收
    Document stuDocument=reader.read("Day40\\src\\students.xml");

    //声明一个学生对象集合用来存解析出学生信息
    List<Student> stuList=new ArrayList();

    /*3.解析xml文件*/
    //获得xml的根节点对象-students
    Element root=stuDocument.getRootElement();
    //获得根节点下面所有子节点-student
    List<Element> childs=root.elements();
    //遍历所有子节点
    for (Element child:childs){
        //创建一个学生对象,用属性来存解析出数据
        Student stu1=new Student();
        //获得节点sid属性值,并将值存在学生对象中
        stu1.setSid(Integer.valueOf(child.attribute("sid").getText()));
        //获得当前节点的子节点属性值
        stu1.setSname(child.element("sname").getText());
        stu1.setSage(Integer.valueOf(child.elementText("sage")));
        stu1.setSsex(child.elementText("ssex"));

        //解析完一个子标签student,将解析出的student对象存在集合中
        stuList.add(stu1);
    }

    //输出解析结果
    for (Student s:stuList){
        System.out.println(s);
    }
}
		
5.Sax解析XML:
	5.1:Sax解析XML原理:基于事件流,自动解析xml文件.
		优点:省内存,自动解析方便.
		缺点:可读性差,不可控制(自动从文件开始解析结尾).
	5.2:Sax解析:jdk自带.
		eg:/**
*sax解析的自定义处理器类
 * @version 1.0
 * @auth sx
 * @date 2020/4/2
 */
public class MyHandle extends DefaultHandler {
    /**
    *声明一个集合存解析出数据
    */
    List<Student> stuList;
    /**
    *声明一个学生对象存当前解析出数据
    */
    Student stu1;
    /**
     *声明一个变量存当前解析标签名
     */
    String tagName;

    /**
    *重写父类中开始解析xml文档的方法
    *@return void
    */
    @Override
    public void startDocument () throws SAXException
    {
        //初始化学生集合
        stuList=new ArrayList();
    }

    /**
    *重写父类中解析每个开始标签的方法
    *@param uri, localName, qName, attributes
    *@return void
    */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //存当前解析标签名,以便后面我们知道解析到哪个标签.
        tagName=qName;
        //如果当前解析标签名叫student
        if ("student".equals(qName)){
            stu1=new Student();
            //获得当前这个student标签的sid属性值,并存在学生对象中
            stu1.setSid(Integer.valueOf(attributes.getValue("sid")));
        }
    }

    /**
    *重写父类中获得每个标签内容的方法
    *@param ch, start, length
    *@return void
    */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        //当前标签内容不为空
        if (ch.length!=0){
            //声明一个变量存当前标签的内容,将数据类型文本内容转换字符串
            String content=new String(ch,start,length);
            //根据标签名判断当前值是对应的是哪个标签的文本值
            if ("sname".equals(tagName)){//姓名
                //将标签文本值存在当前对应学生对象的属性中
                stu1.setSname(content);
            }else if ("ssex".equals(tagName)){//性别
                //将标签文本值存在当前对应学生对象的属性中
               stu1.setSsex(content);
            }else if ("sage".equals(tagName)){//年龄
                //将标签文本值存在当前对应学生对象的属性中
               stu1.setSage(Integer.valueOf(content));
            }
        }
    }

    /**
    *重写父类中解析每个结束标签的方法
    *@param uri, localName, qName
    *@return void
    */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        //如果结束标签为student,说明已经解析完了一个学生对象,将当前解析出学生对象存入集合中
        if ("student".equals(qName)){
            stuList.add(stu1);
        }
    }

    /**
    *重写父类中结束解析xml文档的方法
    *@return void
    */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("当前xml解析完了");
    }
}

		public static void main(String[] args) throws Exception {
    //1.创建sax解析器工厂对象
    SAXParserFactory factory=SAXParserFactory.newInstance();
    //2.用解析器工厂对象创建解析器对象
    SAXParser parser=factory.newSAXParser();
    //3.创建自定义解析器对象的处理器
    MyHandle mh=new MyHandle();
    //4用解析器对象调用解析方法解析xml
    parser.parse("Day40\\src\\students.xml",mh);

    //遍历解析结果
    for (Student s:mh.stuList){
        System.out.println(s);
    }
}

总结:
1.用反射对象操作构造方法.
2.xml的作用:作配置文件;跨平台数据交换格式;作持久存数据文件.
3.xml结构(了解):xml标签规范,xml声明,xml属性,xml注释,xml指令,文档类型声明.
4.xml解析(重点)
4.1:dom4解析
4.2:sex解析

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值