反射
反射(Reflection)是java程序开发语言的特征之一,它允许运行中的java对自身进行检查
反射就是把java类中的各种成分映射成一个个的java对象
加载的时候 : Class对象的由来是将.class文件读入内存,并为之创建一个Class对象
java反射机制,可以实现一下功能
获取源头Class
所有类的对象其实都是Class的实例
获取类的Class对象
获取Class对象
Class是一切反射的源头
第一种对象.class
Source s=new Source();
Class>c1=s.getClass();
System.out.println(c1.getName());
第二种类.class
Class>c2=Source.class;
System.out.println(c2.getName());
第三种Class.forname
Class> c3=Class.forName(“com.shsxt.ref.simple.Source”);
System.out.println(c3.getName());
获取修饰符
获取修饰符,使用 getModifiers() 即可, Modifier 类提供了 static 方法和常量来解码类和成员访问修饰符
方法 :
int getModifiers() 返回此类或接口的Java语言修饰符,以整数编码。
代码 :
Class>clz=Class.forName(“com.shsxt.ref.simple.User”);
//获得修饰符
int n=clz.getModifiers();
//使用Modifier转换为相应的字符串
System.out.println(Modifier.toString(n));
父类与接口
方法:
类>[] getInterfaces() 返回由此对象表示的类或接口直接实现的接口。
类 super T> getSuperclass() 返回 类表示此所表示的实体(类,接口,基本类型或void)的直接超类 类 。
代码
//类 super T> getSuperclass() 返回 类表示此所表示的实体(类,接口,基本类型或void)的直接超类 类 。
Class superClass = cls.getSuperclass();
System.out.println(superClass);
System.out.println(superClass==Object.class);
//类>[] getInterfaces() 返回由此对象表示的类或接口直接实现的接口。Class[] arr = cls.getInterfaces();System.out.println(Arrays.toString(arr));
属性和方法
属性
获取所有属性(包括父类或接口) ,使用 Field 即可操作, Field 作为描述属性的对象
方法
字段 getField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定公共成员字段。
字段[] getFields() 返回一个包含 字段对象的数组, 字段对象反映此 类对象所表示的类或接口的所有可访问公共字段。
字段 getDeclaredField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定声明字段。
字段[] getDeclaredFields() 返回 字段对象的数组, 字段对象反映由此 类对象表示的类或接口声明的所有字段。
学生类 :
package fanshe.field;
public class Student {
public Student(){
}
//**********字段*************//
public String name;
protected int age;
char sex;
private String phoneNum;@Override
public String toString() {return "Student [name=" + name + ", age=" + age + ", sex=" + sex+ ", phoneNum=" + phoneNum + "]";
}
}
测试类
package fanshe.field;
import java.lang.reflect.Field;
public class Fields {
public static void main(String[] args) throws Exception {//1.获取Class对象Class stuClass = Class.forName("fanshe.field.Student");//2.获取字段System.out.println("************获取所有公有的字段********************");Field[] fieldArray = stuClass.getFields();for(Field f : fieldArray){System.out.println(f);}System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");fieldArray = stuClass.getDeclaredFields();for(Field f : fieldArray){System.out.println(f);}System.out.println("*************获取公有字段**并调用***********************************");Field f = stuClass.getField("name");System.out.println(f);//获取一个对象Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();//为字段设置值f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"//验证Student stu = (Student)obj;System.out.println("验证姓名:" + stu.name);System.out.println("**************获取私有字段****并调用********************************");f = stuClass.getDeclaredField("phoneNum");System.out.println(f);f.setAccessible(true);//解除私有限定f.set(obj, "18888889999");System.out.println("验证电话:" + stu);}
}
方法
获取所有方法(包括父类或接口),使用 Method 即可。 Method 即作为描述方法的对象。
方法
方法 getDeclaredMethod(String name, 类>… parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定声明方法。
方法[] getDeclaredMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象表示的类或接口的所有已声明方法,包括public,protected,default(package)访问和私有方法,但不包括继承的方法。
方法 getMethod(String name, 类>… parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定公共成员方法。
方法[] getMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象所表示的类或接口的所有公共方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。
学生类
package fanshe.method;
public class Student {
//成员方法*//
public void show1(String s){
System.out.println("调用了:公有的,String参数的show1(): s = " + s);
}
protected void show2(){
System.out.println(“调用了:受保护的,无参的show2()”);
}
void show3(){
System.out.println(“调用了:默认的,无参的show3()”);
}
private String show4(int age){
System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " + age);
return “abcd”;
}
}
测试类
public class MethodClass {
public static void main(String[] args) throws Exception {//1.获取Class对象Class stuClass = Class.forName("fanshe.method.Student");//2.获取所有公有方法System.out.println("***************获取所有的”公有“方法*******************");stuClass.getMethods();Method[] methodArray = stuClass.getMethods();for(Method m : methodArray){System.out.println(m);}System.out.println("***************获取所有的方法,包括私有的*******************");methodArray = stuClass.getDeclaredMethods();for(Method m : methodArray){System.out.println(m);}System.out.println("***************获取公有的show1()方法*******************");Method m = stuClass.getMethod("show1", String.class);System.out.println(m);//实例化一个Student对象Object obj = stuClass.getConstructor().newInstance();m.invoke(obj, "刘德华");System.out.println("***************获取私有的show4()方法******************");m = stuClass.getDeclaredMethod("show4", int.class);System.out.println(m);m.setAccessible(true);//解除私有限定Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参System.out.println("返回值:" + result);}
}
setAccessible(true):接触私有限定
创建对象
根据Class对象,我们可以获得构造器,为实例化对象做准备。
Class–>newInstance 创建Class对象所有表示类型的的实例–>默认调用空构造
//Class对象
Class cls = ClassEmp.class;
//1.创建对象 Class-->newInstanceClassEmp emp = cls.newInstance();System.out.println(emp);
员工类
public class ClassEmp {
private String name;
private int age;
private int id;
public ClassEmp() {
}public ClassEmp(String name, int age, int id) {this.name = name;this.age = age;this.id = id;
}public String getName() {return name;
}public void setName(String name) {this.name = name;
}public int getAge() {return age;
}public void setAge(int age) {this.age = age;
}public int getId() {return id;
}public void setId(int id) {this.id = id;
}@Override
public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;ClassEmp classEmp = (ClassEmp) o;return age == classEmp.age &&id == classEmp.id &&Objects.equals(name, classEmp.name);
}@Override
public int hashCode() {return Objects.hash(name, age, id);
}@Override
public String toString() {return "ClassEmp{" +"name='" + name + '\'' +", age=" + age +", id=" + id +'}';
}
}
测试类
//2创建构造器
Class cls = ClassEmp.class;
Constructor[] cons = cls.getConstructors();
Arrays.stream(cons).forEach(System.out::println);
Constructorcon=cls.getDeclaredConstructor(String.class,int.class,int.class);
System.out.println(con);
注意 : newInstance()是调用空构造,如果空构造不存在,会出现异常
类加载器
什么是类加载器
类加载器(class loader)用来加载java类到java虚拟机中
系统提供的类jiazaiqi1
类的声明周期
类的加载是通过类加载器完成的的,加载器将 .class 文件的二进制文件装入JVM的方法区,并且在堆区创
建描述这个类的 java.lang.Class 对象。用来封装数据。 但是同一个类只会被类装载器装载一次。
链接就是把二进制数据组装为可以运行的状态。链接分为校验,准备,解析这3个阶段
类加载器
类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance() 方法就可以创建出该类的一个对象。实际的情况可能更加复杂
java中三中类类加载器
public static void main(String[] args) throws Exception {
System.out.println("类加载器
"+ClassLoader.class.getClassLoader().getClass().getName());
}
XML
可扩展的标记语言
版本声明
作用
传输,存储,配置,解析
语法
语言要求严谨,必须严格按照语法进行定义
标签分类
属性
更完整的展示标签的作用
基础语法
XMl文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶"
17 汪小仔格式良好的XML文档需要满足一下条件
实体
实体是对数据的引用;根据实体种类的不同,XML 解析器将使用实体的替代文本或者外部文档的内容来
替代实体引用。
xml中,一些字符拥有特殊的意义。如果把字符 < 放在xml元素中,会发生错误,这是因为解析器会把它当作新元素的开始,这样会产生xml错误
约束
“形式良好”或“结构良好”的 XML 文档拥有正确的语法。合法的 XML 文档是“形式良好”的 XML 文档,并且遵循了特定的约束。
在XML技术里,可以编写一个文档来约束一个XML文档的书写规范(与xml语法无关),这称之为XML约束。此举主要是为了保证数据的规范性和安全性。
DTD约束 : 语法简洁 : 功能比较单一
Schema约束:语法复杂,功能比较强大。
DTD
DTD即文档类型定义-- Document Type Definition
一个DTD文档可能包含如下内容
内部约束
DTD约束和xml写在一个文件中。
语法
]>
王维
外部导入
当验证的XML文件较多时,使用内部DTD可能出现冗余,此时可以通过引入dtd 文件进行xml 约束。
SYSTEM本地文件系统
PUBLIC DTD文件为网络文件,url
Schema
Schema是用一套预先规定的xml元素和属性创建的,这些元素和属性定义了xml文档的结构和内容模式。Xml Shema规定xml文档实例的结构和每个元素/属性的数据类型。
XML解析
xml解析即将文件中的内容按照指定 的含义进行获取
Dom4J解析Xml
解析scores.xml文档
scores.xml
张三 2018001 0113 上海外国语123456 王五 2018002 0114 上海外国语657432
获取document对象SAXReader reader=new SAXReader();
Document document=reader.read(new File("input.xml"));操作xml文档节点Element rootElm=document.getRootElement();//获得根节点
Element memberElm=root.element("member"); //获得子节点
String text=memberElm.getText();//获得节点文本
Element ageElm=newMemberElm.addElement("age");//添加子节点
ageElm.setText("29");//设置节点文本
parentElm.remove(childElm);//)删除某节点例子public static void main(String[] args) throws Exception{SAXReader reader=new SAXReader();Document document=reader.read(new File("src\\source.xml"));Element rootElm=document.getRootElement();//获得根节点Element memberElm=rootElm.element("Student"); //获得子节点Element ageElm=memberElm.addElement("age");//添加子节点ageElm.setText("29");//设置节点文本
// 创建格式化类OutputFormat format = OutputFormat.createPrettyPrint();
// 设置编码格式,默认UTF-8format.setEncoding("UTF-8");
// 创建输出流,此处要使用Writer,需要指定输入编码格式,使用OutputStream则不用FileOutputStream fos = new FileOutputStream("src\\source.xml");
// 创建xml输出流XMLWriter writer = new XMLWriter(fos, format);writer.write(document);
writer.close();
}
注解
jdk1.5新增–> 标注
作用
语法
@注解名(参数)–不需要参数可以省略()
位置
可以定义在任意位置,可以通过Targee规定注解的使用位置
分类