admin管理员组

文章数量:1579416

反射、正则、注解、XML

文章目录

  • 反射、正则、注解、XML
    • 反射
      • 1 Class中常用方法
      • 2 反射操作构造器
      • 3 反射操作属性
      • 4 反射操作方法
      • 5 反射操作数组
    • 正则
      • 1 字符集
        • 1 普通字符
        • 2 元字符与转义
      • 2 字符集
        • 1 自定义
        • 2 默认|标准字符类
        • 3 量词
        • 4 贪婪模式
      • 3 边界
      • 4 选择符与分组
        • 1 选择符 `|`
        • 2 分组 `()`
        • 3 模式修改器
      • 5 零宽断言
      • 10 常用类
        • 1 Pattern
        • 2 Matcher
        • 3 字符串与正则
    • 注解
      • 1 注解的分类
      • 2 内置注解
        • 1 @Override
        • 2 @Deprecated
        • 3 @SupperessWarnings
      • 3 元注解
        • 1 @Target
        • 2 @Retention
        • 3 @Documented
        • 4 @Inherited
      • 4 自定义注解
        • 定义注解格式
        • 注解参数(即方法):
          • 1 修饰符
          • 2 方法类型
          • 3 命名
          • 4 参数
          • 5 默认值
    • XML
      • 1 特点
      • 2 作用
      • 3 语法结构
        • 1 结构
        • 2 标签
        • 3 属性
        • 4 元素
        • 5 实体
          • 预定义实体
      • 6 CDATA
      • XML文档的约束
        • 1 DTD
        • 2 Schema
      • XML解析
        • 1 DOM
        • 2 SAX
        • 3 JDOM
        • 4 DOM4J(推荐)
        • DOM4J解析XML

反射

JAVA有着一个非常突出的动态相关机制:Reflection 发生在程序运行期间的行为

Java反射机制,可以实现以下功能:

①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理;简单通过反射实现的案例,反射大量应用在孔家的底层,第三方的组件封装的时候使用到

反射的源头 : Class类型的对象

类实例表示正在运行的Java应用程序中的类和接口

在一个加载到内存中之后,就会存在这个类的一个Class对象,唯一的,不变的CLass对象中包含这个类的所有内容。
所有反射的源头是Class对象,就相当于获取到了这个类的所有内容,就可以操作使用这些内容。

如何获取反射的源头: Class对象

1、类名.class

Class<String> cls = String.class;
System.out.println(cls.toString());

2、Class.forName(“权限定名”) --> 推荐

Class cls = Class.forName("java.lang.String");
System.out.println(cls.toString());

3、对象.getClass()

Class cls = "".getClass();
System.out.println(cls.toString());

1 Class中常用方法

1、类<?>[] getInterfaces() 返回由此对象表示的类或接口直接实现的接口。

2、int getModifiers() 返回此类或接口的Java语言修饰符,以整数编码。

3、String getName() 权限定名。

4、getPackage() 获取此类的包。

5、String getSimpleName() 返回源代码中给出的基础类的简单名称。

6、boolean isPrimitive() 确定指定的类对象是否表示基本类型。

2 反射操作构造器

1、获取构造器

1)构造器 getConstructor(类<?>... parameterTypes) 返回一个 构造器对象,该对象反映此 类对象所表示的类的指定公共构造函数。

2)构造器<?>[] getConstructors() 返回一个包含 构造器对象的数组, 构造器对象反映了此 类对象所表示的类的所有公共构造函数。

Constructor[] arr = cls.getConstructors();

3)构造器 getDeclaredConstructor(类<?>...parameterTypes) 返回一个构造器对象,该对象反映此 类对象所表示的类或接口的指定构造函数。

Constructor<User> con = cls.getDeclaredConstructor(String.class);

4)构造器<?>[] getDeclaredConstructors() 返回 构造器对象的数组, 构造器对象反映由此 类对象表示的类声明的所有构造函数。

2、通过反射创建对象

1)Class--> newInstace() 默认调用类的空构造为对象初始化信息

2)Constructor --> T newInstace (Object... initargs) 创建对象使用指定当前构造器初始化信息

注意:

用私有内容之前,忽略权限问题:setAccessible()

3 反射操作属性

1、字段 getDeclaredField(String name) 返回字段对象,该对象反映此类对象表示的类或接口的指定声明字段。

2、字段[] getDeclaredFields() 返回 字段对象的数组, 字段对象反映由此 类对象表示的类或接口声明的所有字段。

3、字段 getField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定公共成员字段。

4、字段[] getFields() 返回一个包含 字段对象的数组, 字段对象反映此 类对象所表示的类或接口的所有可访问公共字段。

为属性设置值 void set(Object obj, Object value)

获取属性的值 Object get(Object obj)

4 反射操作方法

1、方法 getMethod(String name, 类<?>...parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定公共成员方法。

2、方法[] getMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象所表示的类或接口的所有公共方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。

3、方法 getDeclaredMethod(String name, 类<?>... parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定声明方法。

4、方法[] getDeclaredMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象表示的类或接口的所有已声明方法,包括public,protected,default(package)访问和私有方法,但不包括继承的方法。

方法的调用:

Object invoke(Object obj, Object... args) 执行当前方法对象 通过参数1调用(成员方法) 返回值:所调用执行方法的返回值

5 反射操作数组

1、创建数组

static Object newInstance(类<?> componentType, int length)
创建具有指定组件类型和长度的新数组。

2、为数组赋值

static void set(Object array, int index, Object value)
将指定数组对象的索引组件的值设置为指定的新值。

3、获取数组中的数据

static Object get(Object array, int index)
返回指定数组对象中索引组件的值。

正则

正则表达式(Regular Expression):用来描述具有一定特征的字符串的特殊字符串。

作用:验证查找替换分割

目标: 简单可以手写,复杂的拷贝,略作修改。

1 字符集

默认情况下区分大小写

1 普通字符

写什么,匹配什么

a b 中国

2 元字符与转义

14个元字符:

( ) [ ] { } \ ^ $ . * + ? |

转义字符:

\+字母

\d —> [0~9]

\\ —> \

\s —> 空白符

\w —> 字母数字_

2 字符集

1 自定义

由 [] 组,只匹配一个, 需要注意以下四个:

^ : 如果在第一个位置,表示取反的含义。

- :表示一个区间即范围

] : 最近一个位置为:结束 ,如果要表示普通的]请加 \

\ : 转义

. : 在字符类中不是代表任意的字符,代表自身 . 的含义。 如果需要表示原有的含义,挪动位置 或者加 \

2 默认|标准字符类

\d:数字[0-9],[0123456789]

\w:字母数字[a-z][A-Z][0-9]

\s:空格,制表符,换行符

\D:非数字[0-9],[0123456789]

\W:非字母数字[a-z][A-Z][0-9]

\S:非空格,制表符,换行符

.

多行模式: 除了换行符以外的任意一个字符

单行模式: 可以匹配包含换行符在内的任意一个字符

3 量词

在匹配的过程中,需要指定次数时使用

* --> 0个及以上

+ --> 1个及以上

? --> 0个或1个

{n} --> n次,非负数

{n,} --> 大于等于n次

{n,m} --> 大于等于n,小于等于m次

4 贪婪模式

在匹配次数不定时如 *, {n,}, + ,匹配字符越多越好,默认模式为“贪婪模式”

贪婪模式greedy:匹配字符越多也好,可回溯

?懒惰模式lazy reluctant:匹配字符越少也好,可回溯 —> +

+独占模式possessive:匹配字符越多越好,不可回溯 —> ?

贪婪模式
.*a
.{2,}a
懒惰模式
.{2,}?a
独占模式
.{2,}+a

阻止贪婪有两种方式

1、 量词后面使用 ?

2、 使用取反

3 边界

边界不占用宽度,只是一个界限

^ :开始

$: 结束

^ : 多行代表每行头 单行代表整个字符串的开始

$ : 多行代表每行尾 单行代表整个字符串的结尾

4 选择符与分组

1 选择符 |

优先级低 ,满足匹配则停止,不会查找更优的方案

匹配 ab c -> ab|c
2 分组 ()

使用小括号"()"来指定要重复的子表达式,然后对这个子表达式进行重复

匹配 ab ac -> a(b|c)

反向引用\ 内部默认缓存,从第一个左括号计算,编号为 1 开始。

必须认识组编号,为 ( 的位置

非捕获组: (?:xxx) : 不缓存组

3 模式修改器

(?ism )字符串(?-ism)

i : insensitive --> 使正则表达式对大小写不敏感;(重点)

s : singleline --> 开启“单行模式”,即点号“.”匹配新行符;

m : multiline --> 开启“多行模式”,即“^”和“$”匹配新行符的前面和后面的位置

(?i)select(?-i) -> 不区分大小写

5 零宽断言

前瞻(Lookahead) 后顾(Lookbehind)

(?=exp) 先行断言,断言自身出现的位置的后面能匹配表达式exp

(?<=exp) 后发断言,断言自身出现的位置的前面能匹配表达式exp

(?!exp) 断言此位置的后面不能匹配表达式exp

(?<!exp) 断言此位置的前面不能匹配表达式exp

(\w+)(?<=ing) –>匹配 singing testing 整个单词 -> 后顾 
(\w+)(?=ing) -->匹配 sing test ->前瞻

10 常用类

java.util.regex包下

一般在查找替换分割组的使用

1 Pattern

常用方法:

1、将给定的正则表达式编译为模式

static Pattern compile(String regex)

2、将给定的正则表达式编译为带有给定标志的模式

static Pattern compile(Sting regex, int flags)

3、创建一个匹配器,匹配给定的输入于此模式

Matcher matcher(CharSequence input)

4、编译给定的正则表达式,并尝试匹配给定的输入

static boolean matches(String regex, CharSequence input)
2 Matcher

常用方法:

1、尝试找到匹配模式的输入序列的下一个子序列

boolean find()

2、重新设置该匹配器,然后尝试从指定的索引开始找到匹配模式的输入序列的下一个子序列

boolean find(int start)

3、尝试将整个区域与模式进行匹配

boolean mathes()
3 字符串与正则

常用方法:

1、告诉这个字符串是否匹配给定的正则表达式

boolean matches(String regex)

2、用给定的替换替换与给定的正则表达式匹配的此字符串的每个子字符串

String replaceAll(string regex, string replacement)

3、将此字符串分割为给定的正则表达式的匹配

String[] split(string regex)

注解

注解(Annotation)是Java 1.5 引入的,目前已被广泛应用于各种Java框架,如Hibernate,Jersey,Spring。

注解相当于是一种嵌入在程序中的 元数据 ,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效,注解解析器能够使用注解决定处理流程。

Java提供了一种元程序中的元素关联任何信息和任何元数据 (metadata)的途径和方法。Annotation是一个接口,程序可以通过反射来获取指定程序元素的Annotation对象,然后通过Annotation对象来获取注解里面的元数据。

元数据描述数据的数据

1 注解的分类

根据直接参数个数分

1、标记注解:没有成员定义的注解类型

2、单值注解:只有一个值

3、完整注解:拥有多个值

根据注解使用方式和用途分

1、JDK内置注解

2、元注解

3、自定义注解

2 内置注解

JavaSE中有三大内置注解,定义在java.lang包中:

1 @Override

限定重写父类方法

2 @Deprecated

标记已过时

3 @SupperessWarnings

抑制编译器警告

3 元注解

作用:负责注解其他注解

Java5.0定义了4个元注解,这些类型和它们所支持的类在java.lang.annotation包中

1 @Target

用于描述注解的使用范围,即被描述的注解可以用在什么地方

表示支持注解的程序元素的种类,如果Target元注解不存在,那么该注解就可以使用在任何程序元素之上

取值(ElementType)有:

CONSTRUCTOR:用于描述构造器

FIELD:用于描述域

LOCAL_VARIABLE:用于描述局部变量

METHOD:用于描述方法

PACKAGE:用于描述包

PARAMETER:用于描述参数

TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Target(ElementType.METHOD) 
@interface TestTarget{ }
//此注解只能用在方法上
2 @Retention

表示需要在什么级别保存该注释信息,用于描述注解的生命周期,表示注解类型保留时间的长短

即被描述的注解在什么范围内有效

取值(RetentionPoicy)有:

SOURCE:在源文件中有效(即源文件保留)

CLASS:在class文件中有效(即class保留)

RUNTIME:在运行时有效(即运行时保留)

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
@interface TestRetention{ }
//该注解运行时有效。
//注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理 
3 @Documented

表示使用该注解的元素应被javadoc或类似工具文档化,应用于类型声明,类型声明的注解会影响客户端对注解元素的使用,@Documented是一个标记注解。

@Documented 
@interface TestDocumented{ }
//可以被例如javadoc此类的工具文档化 
4 @Inherited

表示一个注解类型会被自动继承

@Inherited 
@interface TestInheri{ }
//被子类继承的注解 

4 自定义注解

自己定义的注解,让别人去使用

完整的注解分两块,一块是注解的定义,与之配套的会有相应的解析器

@interface:用来声明一个注解

注解类里的每一个方法实际上是声明了一个配置参数

方法的名称就是参数的名称

返回值类型就是参数的类型(返回值类型只能是基本类型ClassStringenum

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

定义注解格式
public @interface 注解名{
    定义体
}
注解参数(即方法):
1 修饰符

只能用public或默认(default)这两个访问权修饰 ,默认为default

2 方法类型

注解体中的方法的返回值,作为注解参数,只支持以下数据类型

基本数据类型(byte,short,int,long,float,double,char,boolean); 
String类型; 
Class类型; 
enum类型; 
Annotation类型; 
以上所有类型的数组
3 命名

如果只有一个参数成员,最好把参数名称设为"value",后加小括号

4 参数

注解中的方法不能存在参数

5 默认值

可以包含默认值,使用default来声明默认值

XML

可扩展标记语言(Extensive Markup Language),xml是互联网数据传输的重要工具,它可以跨越互联网任何的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者

Xml用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

Xml是标准通用标记语言(SGML)的子集,非常适合Web传输。XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

1 特点

1、xml与操作系统、编程语言 的开发平台都无关

2、实现不同系统之间的数据交互

2 作用

1、配置应用程序(servlet配置,框架环境配置等)和网站

2、数据交互

3、Ajax基石

3 语法结构

1 结构

XML文档形成一种树结构,它从根部开始,然后扩展到枝叶。

必须包含一个2根元素,该元素是所有其他元素的父元素,所有元素均可拥有子元素

格式良好的 XML 文档需满足以下条件

1、必须有XML声明语句 (第一行)

2、必须有且仅有一个根元素

3、标签成对

4、元素正确嵌套

2 标签

在 xml 中通过一对 <> 引起来的内容称为标签

标签有开始有结束(也可以有自闭合标签),需正确配对,开始标签和结束标签之间只差一个 /

标签区分大小写

3 属性

属性为标签添加了一些额外信息,属性的形式为 属性名 = “属性值”

一个标签中可以存在多个属性

4 元素

开始标签到结束标签作为一个整体,称为元素

xml文件就是由一个一个的元素组成的

5 实体

实体是对数据的引用

根据实体种类的不同,XML 解析器将使用实体的替代文本或者外部文档的内容来替代实体引用

预定义实体

xml中,一些字符拥有特殊的意义

实体符号
&lt;<
&gt;>
&amp;&
&quot;*
&apos;.

6 CDATA

PCDATA 指的是被解析的字符数据(Parsed Character Data)

XML 解析器通常会解析 XML 文档中所有的文本

当某个 XML 元素被解析时,其标签之间的文本也会被解析

所有 XML 文档中的文本均会被解析器解析。

只有 CDATA 区段 (CDATA section)中的文本会被解析器忽略。

CDATA 部分由 <![CDATA[ 开始,由 ]]> 结束

XML文档的约束

形式良好或结构良好的 XML 文档拥有正确的语法。

合法的XML 文档是“形式良好”的 XML 文档,并且遵循了特定的约束。

在XML技术里,可以编写一个文档来约束一个XML文档的书写规范(与xml语法无关),这称之为XML约束。

此举主要是为了保证数据的规范性和安全性

DTD约束:语法简洁,功能比较单一。

Schema约束:语法复杂,功能比较强大。

1 DTD

DTD即文档类型定义 —> Document Type Definition

一个DTD文档可能包含如下内容:

1、元素的定义规则

2、元素之间的关系规则

3、属性的定义规则

内部导入:DTD约束和xml写在一个文件中

外部导入:当验证的XML文件较多时,使用内部DTD可能出现冗余,此时可以通过引入dtd 文件进行xml 约束

2 Schema

Schema是用一套预先规定的xml元素和属性创建的,这些元素和属性定义了xml文档的结构和内容模式。

Xml Shema规定xml文档实例的结构和每个元素**/**属性的数据类型。

XML解析

将文件中的内容按照指定的含义进行获取

四种XML解析方式

1 DOM
  • 基于XML树结构
  • 比较耗资源
  • 适用于多次访问XML
2 SAX
  • 基于事件
  • 消耗资源小
  • 适用于数据量较大的XML
3 JDOM
  • 比DOM更快
  • JDOM仅使用具体类而不使用接口
4 DOM4J(推荐)
  • 非常优秀的Java XML API
  • 性能优异、功能强大
  • 开放源代码
DOM4J解析XML

DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件

API文档参考地址:https://dom4j.github.io/

本文标签: 正则注解一篇文章反射教会