• 2022.08.16 java学习


    1.反射
    • 反射是指对于任何一个Class类,在“运行的时候”都可以直接得到这个类的全部成分;这种运行时动态获取类信息以及动态调用类中成分的能力称为Java的反射机制
    • 在运行时获取类的字节码文件对象(Class文件),然后解析类中的全部成分
    2.反射获取Class类对象
    • 源代码阶段:Class.forName(String className)
      • 其中className为全限名:包名+类名
    • Class对象阶段:类名.class
    • Runtime运行时阶段:对象.getClass()
    3.反射获取构造器对象

    Class类中用于获取构造器的方法:

    方法说明
    Constructor[ ] getConstructors()返回所有构造器对象的数组(只能拿public的)
    Constructor[ ] getDeclaredConstructors()返回所有构造器对象的数组,存在就能拿到
    Constructor< T> getConstructor(Class… parameterTypes)按照参数类型定位并返回单个构造器对象(只能拿public的)
    Constructor< T> getDeclaredConstructor(Class… parameterTypes)返回单个构造器对象,存在就能拿到

    Constructor类中用于创建对象的方法:

    方法说明
    T newInstance(Object… initargs)根据指定的构造器创建对象
    public void setAccessible(boolean flag)设置为true,表示取消访问检查(private),进行暴力反射
    4.反射获取成员变量对象
    • 先获取类对象,然后从类对象中获取类的成分对象

    Class类中用于获取成员变量的方法:

    方法说明
    Field[ ] getFields()返回所有成员变量对象的数组(只能拿public)
    Field[ ] getDeclaredFields()返回所有成员变量对象的数组,存在就能拿到
    Field getField(String name)返回单个成员变量对象(只能拿public的)
    Field getDeclaredField(String name)返回单个成员变量对象,存在就能拿到

    Field类中用于取值、赋值的方法

    方法说明
    void set(Object obj, Object value)赋值
    Object get(Object obj)取值

    如果某成员变量是非public的,需要打开权限进行暴力反射,然后再取值、赋值;setAccessible(boolean)

    5.反射获取方法对象

    Class类中用于获取成员方法的方法

    方法说明
    Method[ ] getMethods()返回所有成员方法对象的数组(只能拿public的)
    Method[ ] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到
    Method getMethod(String name, Class… parameterTypes)返回单个成员方法对象(只能拿public的)
    Method getDeclaredMethod(String name, Class… parameterTypes)返回单个成员方法对象,存在就能拿到

    Method类中用于触发执行的方法

    方法说明
    Object invoke(Object obj, Object… args)运行方法,参数一:用obj对象调用该方法;参数二:调用方法的传递的参数
    6.反射的作用–绕过编译阶段为集合添加数据
    • 反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以为集合存入其他任意类型的元素的
    • 泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段时,其真实类型都是ArrayList了,泛型被擦除
    7.反射的作用
    • 可以在运行时得到一个类的全部成分然后操作
    • 可以破坏封装性(private)(很突出)
    • 可以破坏泛型的约束性(很突出)
    • 更重要的用途是适合做Java高级框架
    8.注解(Annotation)
    • 对Java中类、方法、成员变量做标记,然后进行特殊处理

    自定义注解—格式

    public @interface 注解名称{
    	public 属性类型 属性名() default 默认值;
    }
    
    • 1
    • 2
    • 3

    特殊属性:

    • value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写
    • 但是如果有多个属性,且多个属性没有默认值,那么value名称是不能省略的

    元注解:

    • @Target:约束自定义注解只能在哪些地方使用(比如只能在方法使用)
    • @Retention:申明注解的生命周期
    @Target(ElementType.METHOD, ELementType.FIELD)
    public @interface MyTest{
    }
    
    • 1
    • 2
    • 3

    @Target可使用的值定义在ElementType枚举类中,常用值如下:

    • Type:类、接口
    • FIELD:成员变量
    • METHOD:成员方法
    • PARAMETER:方法参数
    • CONSTRUCTOR:构造器
    • LOCAL_VARIABLE:局部变量

    @Retention可使用的值定义在RetentionPolicy枚举类中,常用值如下:

    • SOURCE:注解只作用在源码阶段,生成的字节码文件中不存在
    • CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值
    • RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段 (开发常用)
    9.注解的解析
    • 判断注解是否存在,存在注解就解析出内容

    与注解解析相关的接口:

    • Annotation:注解的顶级接口,注解都是Annotation类型的对象
    • AnnotatedElement:该接口定义了与注解解析相关的解析方法
    方法说明
    Annotation[ ] getDeclaredAnnotations()获得当前对象上使用的所有注解,返回注解数组
    T getDeclaredAnnotation(Class< T> annotationClass)根据注解类型获得对应注解对象
    boolean isAnnotationPresent(Class< Annotation> annotationClass)判断当前对象是否使用了指定的注解,如果使用了则返回true,否则false

    解析注解的技巧:

    • 注解在哪个成分上,我们就要先拿哪个成分对象
    • 成员方法:先获得该成员方法对应的Method对象,再拿上面的注解
    10.动态代理

    如何创建代理对象:

    • Java中代理的代表类是:java.lang.reflect.Proxy
    • Proxy提供了一个静态方法,用于为对象产生一个代理对象返回
    public static Object newProxyInstance(ClassLoader loader, Class<?>[ ] interfaces, InvocationHandler h)
    为对象返回一个代理对象
    参数一:定义代理类的类加载器
    参数二:代理类要实现的接口列表
    参数三:将方法调用分派到的处理程序(代理对象的核心处理程序)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    下面是为一个实现Skill接口的Star类的代理类StarAgentProxy

    public class StarAgentProxy{
    	public static Skill getProxy(Star obj){
    		return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
    						obj.getClass().getInterfaces(), new InvocationHandler(){
    							@Override
    							public Object invoke(Object proxy, Method method, Object[ ] args) throws Exception{
    									System.out.println("收首付款");  //代理做的
    									Object rs = method.invoke(obj, args);  //真正对象做的
    									System.out.println("收尾款,把明星接回来"); //代理做的
    									return rs;
    									}
    							});
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    前两个参数都是固定的,第三个需要自己重写,代理类也都实现了原始类的接口,因为想要调用原始类的方法时都得通过代理类进行

    在这里插入图片描述
    实现动态代理:

    • 必须存在接口
    • 被代理对象需要实现接口
    • 使用Proxy类提供的方法,得到对象的代理对象

    当左右方法前面需要干的事情和后面需要干的事情一致时,我们可以考虑使用代理,例如测试每个方法的运行时间。而且可扩展性超级强,之后原对象里再添加方法,可以直接走代理

    11.动态代理的优点
    • 可以在不改变方法源码的情况下,实现对方法功能的增强,提高了代码的复用
    • 简化了编程工作,提高了开发效率,以高了软件系统的可扩展性
    • 可以为被代理对象的所有方法做代理
    • 非常灵活,支持任意接口类型的实现类对象做代理(将Skill类型改成泛型< T>,也可以为接口本身做代理
    12.XML

    XML特点和使用场景:

    • 一是纯文本,默认使用UTF-8;二是可嵌套
    • 使用场景:XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的信息

    XML的语法规则

    • 文档声明必须是第一行
    
    version:XML默认的版本号码
    encoding:本XML文件的编码
    
    • 1
    • 2
    • 3

    XML的标签(元素)规则

    • 标签由一对尖括号和合法标识符组成:< name>< /name>,必须存在一个根标签,有且只能有一个
    • 标签必须成对出现,有开始,有结束
    • 特殊的标签可以不成对,但是必须有结束标记,如:< br/>
    • 标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来< student id=“1”>< /student>

    XML的其他组成

    • XML文件中可以定义注释信息:< !-- 注释内容 -->
    • XML文件中可以存在以下特殊字符
    < < 小于
    > > 大于
    & & 和号
    ' ' 单引号
    " " 引号
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • XML文件中可以存在CDATA区:(里面的内容可以随便写,不用担心冲突)
    13.文档约束
    • 用来限定xml文件中的标签以及属性应该怎么写。
    • 分类:DTD和schema

    DTD

    • 可以约束格式,但不能约束数据类型

    schema

    • 可以约束具体的数据类型,约束能力上更强大
    • 后缀是.xsd(xml schema 约束)
    14.XML解析技术
    • SAX解析:一行行解析,适合大文件
    • DOM解析(dom4j):将整个文件加载到内存,适合小文件

    在这里插入图片描述
    Dom解析的文档对象模型:

    • Document对象:整个xml文档
    • Element对象:标签
    • Attribute对象:属性
    • Text对象:文本内容
    • Element、Attribute、Text三者都是Node对象
    15.Dom4j:用于解析数据

    得到Document对象:

    SAXReader类

    方法说明
    public SAXReader()创建Dom4J的解析器对象
    Document read(String url)加载XML文件成为Document对象

    Document类

    方法说明
    Element getRootElement()获取根元素对象

    Dom4j解析XML的元素、属性、文本

    方法名说明
    List< Element> elements()得到当前元素下所有一级子元素
    List< Element> elements(String name)得到当前元素下指定名字的子元素返回集合
    Element element(String name)得到当前元素下指定名字的子元素,如果重名返回第一个
    String getName()得到元素名字
    String attributeValue(String name)通过属性名直接得到属性值
    String elementText(子元素名)得到指定名称的子元素的文本
    String getText()得到文本
    16.XPath:进行信息检索

    使用Xpath检索XML文件:

    • 导入jar包(dom4j和jaxen-1.1.2.jar),Xpath技术依赖Dom4j技术
    • 通过dom4j的SAXReader获取Document对象
    • 利用Xpath提供的API,结合XPath的语法完成选取XML文档元素进行节点解析操作
    • Document中与Xpath相关的API如下:
    方法名说明
    Node selectSingleNode(“表达式”)获取符合表达式的唯一元素
    List< Node> selectNodes(“表达式”)获取符合表达式的元素集合

    XPath:绝对路径

    • 采用绝对路径获取从根节点开始逐层的查找
    方法名说明
    /根元素/子元素/孙元素从根元素开始,一级一级向下查找,不能跨级

    XPath:相对路径

    • 先得到根节点,在采用相对路径一级一级向下查找
    方法名说明
    ./子元素/孙元素从当前元素开始,一级一级向下查找,不能跨级

    XPath:全文搜索

    • 直接全文搜索所有的name元素并打印
    方法名说明
    //name找名称为name的元素,无论元素在哪里
    //contact/name找contact,无论在哪一级,但name一定是contact的子节点
    //contact//namecontact无论在哪一种,name只要是contact的子孙元素都可以找到

    XPath:属性查找

    • 在全文中搜索属性,或者带属性的元素
    方法名说明
    //@属性名查找属性对象,无论是哪个元素,只要有这个属性即可
    //元素[@属性名]查找元素对象,全文搜索指定元素名和属性名
    //元素[@属性名=‘值’]查找元素对象,全文搜索指定元素名和属性名,并且属性值相等
  • 相关阅读:
    Stable Diffusion 动画animatediff-cli-prompt-travel
    TiFlash 函数下推必知必会丨十分钟成为 TiFlash Contributor
    使用canal实现数据实时同步
    [附源码]SSM计算机毕业设计健身健康规划系统JAVA
    图像采集 deep OCR
    JVM | 命令行诊断与调优 jhsdb jmap jstat jps
    冒泡排序记录
    多模态大模型的应用探索:多样场景下的创新实践
    Java中ExecutorService线程池的使用(Runnable和Callable多线程实现)
    Angular, React,Vus三大主流前端开发框架Setup
  • 原文地址:https://blog.csdn.net/qq_43601664/article/details/126359003