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 默认值;
}

特殊属性:

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

元注解:

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

@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)
为对象返回一个代理对象
参数一:定义代理类的类加载器
参数二:代理类要实现的接口列表
参数三:将方法调用分派到的处理程序(代理对象的核心处理程序)

下面是为一个实现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;
									}
							});
	}

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

2022.08.16 java学习_第1张图片
实现动态代理:

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

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

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

XML特点和使用场景:

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

XML的语法规则

  • 文档声明必须是第一行

version:XML默认的版本号码
encoding:本XML文件的编码

XML的标签(元素)规则

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

XML的其他组成

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

DTD

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

schema

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

2022.08.16 java学习_第2张图片
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//name contact无论在哪一种,name只要是contact的子孙元素都可以找到

XPath:属性查找

  • 在全文中搜索属性,或者带属性的元素
方法名 说明
//@属性名 查找属性对象,无论是哪个元素,只要有这个属性即可
//元素[@属性名] 查找元素对象,全文搜索指定元素名和属性名
//元素[@属性名=‘值’] 查找元素对象,全文搜索指定元素名和属性名,并且属性值相等

你可能感兴趣的:(java,学习,jvm)