什么是反射?
是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展
获取类对象:
类名.Class属性 ===》 person.Class; ===> Class aClass = Person.class;
对象名.getClass方法 ===》 person.getClass(); ===> Class aClass = person.getClass();
Class.forName(全类名)方法 ===》 Class aClass = Class.forName(“com.smiledog.fanshe.Person”); 主要使用
获取类对象的成员变量,构造函数,方法:
package com.smiledog.fanshe;/*@ClassName GetFanSheDemo@Author SmILeDog@Date 2021/5/12@Time 12:52通过获得类对象获取的对象的数据*/import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class GetFanSheDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException {//获取类实例Class classzz = Class.forName("com.smiledog.fanshe.Person");//获取类全路径String name = classzz.getName();//System.out.println(name);//获取公开构造Constructor[] cons1 = classzz.getConstructors();for (Constructor con : cons1) {System.out.println(con);}System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取所有构造Constructor[] cons2 = classzz.getDeclaredConstructors();for (Constructor con : cons2) {System.out.println(con);}System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取指定参数构造Constructor con1 = classzz.getConstructor(String.class);System.out.println(con1);System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取公有方法Method[] methods = classzz.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取所有方法Method[] declaredMethods = classzz.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod);}System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取指定方法名的方法Method eat = classzz.getDeclaredMethod("eat");System.out.println(eat);System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取公有成员变量Field[] fields = classzz.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取所有成员变量Field[] declaredFields = classzz.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(declaredField);}System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");//获取指定成员变量Field name1 = classzz.getDeclaredField("name");System.out.println(name1);}}
操作获取的类对象数据:
package com.smiledog.fanshe;/*@ClassName UseFanSheDemo@Author SmILeDog@Date 2021/5/12@Time 14:55通过获得类对象操作获取的对象的数据*/import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class UseFanSheDemo {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {Class<?> classzz = Class.forName("com.smiledog.fanshe.Person"); //获取类对象//使用构造方法//Constructor<?> con1 = classzz.getDeclaredConstructor(String.class); //获取构造方法//Object obj1 = con1.newInstance("10010"); //实例化对象//System.out.println(obj1); //打印对象//使用私有构造方法 不建议使用,既然是私有,强制反射的话出现安全问题//Constructor<?> con2 = classzz.getDeclaredConstructor(int.class); //获取私有构造方法//con2.setAccessible(true); //强制反射,,不加找不到私有构造,//不建议。。。。//Object obj2 = con2.newInstance(100);//System.out.println(obj2);// //使用方法// Object o = classzz.newInstance(); //实例化// Method eatmethod = classzz.getMethod("eat"); //获取指定方法// eatmethod.invoke(o); //调用指定对象的方法// //使用私有方法// Method showmethod = classzz.getDeclaredMethod("show"); //获取指定方法// showmethod.setAccessible(true); //暴力反射// showmethod.invoke(o); //调用指定对象的方法//使用成员变量// Object o = classzz.newInstance(); //实例化// Field id = classzz.getField("id"); //获取指定成员变量// id.set(o,"id:001"); //给指定对象赋值// Object o1 = id.get(o); //获取指定对象的成员变量// System.out.println(o1); //打印该对象//使用私有成员变量Object o = classzz.newInstance(); //实例化Field name = classzz.getDeclaredField("name");//获取指定的私有成员变量name.setAccessible(true); //强制反射该对象name.set(o,"姓名:杀杀杀"); //给指定对象赋值Object o1 = name.get(o); //获取指定对象的私有成员变量System.out.println(o1); //打印该对象}}
反射&Properties案例:
package com.smiledog.fanshe.fanshedemo;/*@ClassName Person@Author SmILeDog@Date 2021/5/12@Time 12:52*/public class Person {public String id;public String name;public int age;public void eat(){System.out.println("干饭 .....");}public void sleep(){System.out.println("碎觉 ......");}private void play(){System.out.println("打豆豆 ......");}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~package com.smiledog.fanshe.fanshedemo;/*@ClassName FanSheDemo@Author SmILeDog@Date 2021/5/12@Time 15:54使用properties配置文件,进行反射的相关操作*/import java.io.*;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Properties;public class FanSheDemo {public static void main(String[] args) throws ClassNotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {FileReader fw = new FileReader(new File("person.properties"));//day16/person.properties//读取配置文件Properties pro = new Properties();pro.load(fw);String className = pro.getProperty("className");String methodName = pro.getProperty("methodName");//反射Class<?> aClass = Class.forName(className);Object obj = aClass.newInstance();Method method = aClass.getDeclaredMethod(methodName); //为避免获取私有方法,直接调用获取所有方法的方法method.setAccessible(true); //且强制反射method.invoke(obj);}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~person.properties~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~className=com.smiledog.fanshe.fanshedemo.PersonmethodName=play
XML:
xml与html的区别:
html:用来展示数据的
xml:用来储存数据,持久化,配置文件【在网络中传输数据,后被json取代】
xml的基础语法:
1、xml文档的后缀名必须是:. xml
2、xml文档的第一行必须定义为:文档声明
3、xml文档有且仅有一个根标签
4、属性值必须使用引号(单引号或双引号)引起来
5、标签必须正确关闭,也就是双标签的规范
6、xml文档严格区分大小写
xml的快速入门:
使用xml描述学生信息:
<?xml version="1.0" encoding="utf-8" ?><!--This XML file does not appear to have any style information associated with it. The document tree is shown below.--><!--此XML文件似乎没有任何与之关联的样式信息。文档树如下所示。--><Students><student id="it001"><name>张三</name><age>13</age><sex>男</sex></student><student id="it002"><name>李四</name><age>14</age><sex>男</sex></student></Students>
xml的组成部分:
1、文档声明:
格式:
<?xml 属性列表 ?>
属性列表:
version:版本号:【1.0】
encoding:编码方式【默认值:ISO-8859-1】
standalone:是否独立【yes:不依赖其他文件 no:依赖其他文件】
2、指令:(不重要)
3、标签命名规则: (总之一句话:简洁明了)
名称可以包含字母,数字以及其他的字符
名称不能以数字或标点符号开始
名称不能以字母xml开始
名称不能包含空格
不要用 双引号,逗号,冒号,
xml命名经验之谈,文档经常有一个对应的数据库,最好根据数据库的命名规则来命名
4、属性:使用单引号和双引号
属性值唯一(官方说法)
5、文本:就是双标签里边的数据
转义字符:
<;:< 小于
>;:> 大于
&;:& 和
&apos;:’ ‘ 单引号
";:” “ 双引号
转成文本数据 :<![CDATA[ 文本内容 ]]>
xml的约束:
规定xml的书写规则
DTD约束:
新建一个文件,文件的扩展名是(.dtd)
<!ELEMENT students (student*) > //根标签下有一个或多个子标签<!ELEMENT student (name,age,sex)> //子标签里边的子标签,且有顺序<!ELEMENT name (#PCDATA)> //该标签中写文本<!ELEMENT age (#PCDATA)><!ELEMENT sex (#PCDATA)><!ATTLIST student number ID #REQUIRED> //子标签的属性唯一~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE students SYSTEM "student.dtd"><students><student number="001"><name>张三</name><age>13</age><sex>男</sex></student></students>
Schema约束:
新建一个文件,文件的扩展名是:(.xsd)
<?xml version="1.0"?><xsd:schema xmlns="(命名空间:公司域名)/xml"xmlns:xsd="http://www.w3.org/2001/XMLSchema" //固定写法targetNamespace="(命名空间:公司域名)/xml" elementFormDefault="qualified"><xsd:element name="students" type="studentsType"/><xsd:complexType name="studentsType"><xsd:sequence><xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/></xsd:sequence></xsd:complexType><xsd:complexType name="studentType"><xsd:sequence><xsd:element name="name" type="xsd:string"/> //指定类型<xsd:element name="age" type="ageType" /> //自定义类型<xsd:element name="sex" type="sexType" /></xsd:sequence><xsd:attribute name="number" type="numberType" use="required"/></xsd:complexType><xsd:simpleType name="sexType"> //自定义类型的格式<xsd:restriction base="xsd:string"> //自定义类型内容的类型<xsd:enumeration value="male"/> //指定内容范围 :单选<xsd:enumeration value="female"/></xsd:restriction></xsd:simpleType><xsd:simpleType name="ageType"> //自定义类型的格式<xsd:restriction base="xsd:integer"> //自定义类型内容的类型<xsd:minInclusive value="0"/> //指定内容范围 :数值范围<xsd:maxInclusive value="100"/></xsd:restriction></xsd:simpleType><xsd:simpleType name="numberType"> //自定义类型的格式<xsd:restriction base="xsd:string"> //自定义类型内容的类型<xsd:pattern value="itfxp_\d{4}"/> //正则表达式 :内容格式:(itfxp_开头 加上 四位数)</xsd:restriction></xsd:simpleType></xsd:schema>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<?xml version="1.0" encoding="UTF-8" ?><!--1.填写xml文档的根元素2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //固定写法3.引入xsd文件命名空间. xsi:schemaLocation="(命名空间:公司域名)/xml student.xsd"4.为每一个xsd约束声明一个前缀,作为标识 xmlns="(命名空间:公司域名)"--><students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="(命名空间:公司域名)"xsi:schemaLocation="(命名空间:公司域名)/xml student.xsd"><student number="itfxp_0010"><name>张三</name><age>100</age><sex>male</sex></student></students>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
