反射Reflection
基础知识
反射机制
反射机制 : 是JAVA有着一个非常突出的动态相关机制
注意 : 发生在程序运行期间
功能:
Java反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理;
反射的源头:
Class : 类类实例表示正在运行的Java应用程序中的类和接口。
Class类型的对象在类加载到内存后就存在的,是独一份的,我们不能创建只能获取
获取Class对象:
1.类名.class
2.对象.getClass()
3.Class.forName(权限定名) -------> 推荐

**特点:**Class对象加载到内存后就已经存在了,独一份的,不会改变。
反射操作
反射创建对象
1.Class-->newInstance() ------> 不推荐
默认调用空构造
2.Constructor--> T newInstance(Object... initargs)
1)获取类型的构造器
构造器<T> getConstructor(类<?>... parameterTypes)
构造器<?>[] getConstructors()
构造器<T> getDeclaredConstructor(类<?>... parameterTypes)
构造器<?>[] getDeclaredConstructors()
2)创建对象时候调用指定构造器初始化信息
Constructor--> T newInstance(Object... initargs)
反射操作属性
1)获取属性
(1)字段 getDeclaredField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定声明字段。
(2)字段[] getDeclaredFields() 返回 字段对象的数组, 字段对象反映由此 类对象表示的类或接口声明的所有字段。
(3)字段 getField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定公共成员字段。
(4)字段[] getFields() 返回一个包含 字段对象的数组, 字段对象反映此 类对象所表示的类或接口的所有可访问公共字段。
2)使用属性
设置属性值
void set(Object obj, Object value) 将指定对象参数上此 字段对象表示的字段设置为指定的新值。
获取属性值
Object get(Object obj) 返回指定对象上此 字段表示的字段的值。
反射操作方法
1) 获取方法
(1)方法 getDeclaredMethod(String name, 类<?>... parameterTypes)
(2)方法[] getDeclaredMethods()
(3)方法 getMethod(String name, 类<?>... parameterTypes)
(4)方法[] getMethods()
2) 调用方法
Object invoke(Object obj, Object... args)
注解Annotation
基础知识
定义
标注,jdk1.5新特性
作用
1.注释的作用
2.标志检查的作用
3.使用注释时候同时传递配置数据,程序执行过程中通过反射操作配置的数据
4.注解可以存在与Class文件中
格式 :@注解名(参数)
位置
应用在任意位置,具体可以根据需求作用通过元注解进行设置
分类
1.jdk内置注解
@Override 强制检测一个方法是否为重写方法
@Deprecated 标记已过时
@SuppressWarnings 抑制编译器警告
@FunctionalInterface 强制检测一个接口是否为函数式接口
2.参数个数分类
标记注解 : 没有参数
单值注解 : 参数只有一个
完整注解 : 参数多个
3.元注解
注解注解的注解
@Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方)。
@Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期
@Documented 表示使用该注解的元素应被javadoc或类似工具文档化
@Inherited 表示一个注解类型会被自动继承,
@Repeatable 让一个注解类型在一个位置可以同时使用多次
4.自定义注解 : 了解
1.@interface定义注解类型;
2.默认隐式的实现了java.lang.annotation.Annotation接口 所有注释类型扩展的公共接口;
2.自定义的注解类型不能显示的实现其他接口,继承其他父类;
4.如果定义注解类型中定义了字段,使用注解类型时必须配置参数为字段赋值;
5.注解类型中的字段 : 数据类型 字段名();
6.数据类型只能为 : 基本数据类型 字符串 注解类型 枚举类型 以上类型的数组;
7.如果注解类型中字段只有一个,建议字段名定义为value,在传递实参时候,可以直接赋值;
8.如果注解类型中存在字段,可以通过default为字段设置默认值;
注意 : 如果运行期间想要通过反射操作注解,一定要为注解类型设置生命周期为运行期
@SuppressWarnings("all")
@MyAnno
public class Class001_Annotation {
@MyAnno
public static void main(String[] args) {
@SuppressWarnings("all")
List list = new ArrayList();
List list2 = new ArrayList();
}
@Deprecated
public static void test(){
List list = new ArrayList();
}
}
@Inherited
@Target({ElementType.METHOD,ElementType.TYPE})
@interface MyAnno{}
debug : 调试工具
作用 :
1.追踪程序的执行流程
2.定位到异常出现的位置
3.观察程序执行过程中变量变化的情况
4.根据程序的执行流程学习一些第三方的框架的源码
使用 :
1.设置断点 : 行号的后面单击设置断点,单击取消
2.debug模式运行
F8 : Step over 下一步跳过,如果是方法的不会进入方法跟随执行,直接到方法执行完毕情况;
F7 : Step into 下一步进入(步入),如果是自定义方法的调用,会跟随方法进入执行每一步,但是如果是jdk源码,不会跟随执行;
alt+shift+F7 : Force Step into 下一步强制进入(步入),但是如果是jdk源码,会强制进入跟随执行;
shift+F8 : Step out 步出,从方法内部跳出到方法调用的位置;
alt+F9 : run to cursor 运行到光标所在位置;
public class Class001_Debug {
public static int a = 0;
{
a = 10;
System.out.println("3 、非静态代码块执行a=" + a); //10
}
static {
a = 6;
System.out.println("1、静态代码块执行a=" + a); //6
}
public Class001_Debug() {
this(a);
System.out.println("6、"+a); //10
System.out.println("7、无参构造方法执行a=" + a); //10
}
public Class001_Debug(int n) {//6
System.out.println("4、"+n); //6
System.out.println("5、"+a);//10
}
public static void main(String[] args) {
System.out.println("2、main"); //main
Class001_Debug tsc = new Class001_Debug();
}
}
XML
DOM4J解析XML文件 :
步骤 :
1.下载jar包
2.放入项目lib目录下,右键add as lib..
3.java代码中解析使用 了解
遍历获取
修改
删除
创建
写出
public class Class001_XML {
public static void main(String[] args) throws DocumentException {
//1.构建输入流
SAXReader reader=new SAXReader();
//2.加载XML文件,获取Document对象
Document document=reader.read(new File("src\\persons.xml"));
//3.获取根元素
Element rootElement=document.getRootElement();//获得根节点
System.out.println("根元素的名字 = "+rootElement.getName());
//获取所有的子标签
List<Element> list = rootElement.elements();
list.stream().forEach(e->{
System.out.println("---->"+e.getName()+"--> id = "+e.attributeValue("id"));
//迭代每一个子元素
//获取遍历当前元素所有子元素的迭代器
Iterator<Element> it = e.elementIterator();
while(it.hasNext()){
Element ele = it.next();
System.out.println("----------->"+ele.getName()+"---->"+ele.getText());
}
});
}
}
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
/*
DOM4J解析XML文件 :
步骤 :
1.下载jar包
2.放入项目lib目录下,右键add as lib..
3.java代码中解析使用 了解
遍历获取
修改
删除
创建
写出
*/
public class Class002_XML {
public static void main(String[] args) throws IOException, DocumentException {
//writeToFile(createDocument(),"src/dest.xml");
writeToFile(change(getDocument("src/persons.xml")),"src/persons.xml");
}
//创建Document对象,添加元素标签,属性,文本
public static Document createDocument(){
Document document = DocumentHelper.createDocument();
Element root = document.addElement("root");
Element author1 = root.addElement("author")
.addAttribute("name", "James")
.addAttribute("location", "UK")
.addText("James Strachan");
Element author2 = root.addElement("author")
.addAttribute("name", "Bob")
.addAttribute("location", "US")
.addText("Bob McWhirter");
return document;
}
//写出
public static void writeToFile(Document document,String dest) throws IOException {
//构建输出流,指定输出格式
XMLWriter writer = new XMLWriter(new FileWriter(dest), OutputFormat.createPrettyPrint());
//写出
writer.write(document);
//刷出
writer.flush();
//关闭
writer.close();
}
//修改与删除
public static Document change(Document document){
//删除id为1002的子元素Person
Element root = document.getRootElement();
List<Element> list = root.elements();
list.forEach(e->{
String value = e.attributeValue("id");
if("1002".equals(value)){
root.remove(e);
}
//把姓名为张三的人名字改为张三丰
Element element = e.element("name");
if("张三".equals(element.getText())){
element.setText("张三丰");
}
});
return document;
}
//获取Document
public static Document getDocument(String path) throws DocumentException {
SAXReader reader=new SAXReader();
//2.加载XML文件,获取Document对象
Document document=reader.read(new File(path));
return document;
}
}