Java笔记之动态特性

2019-01-20  本文已影响0人  码匠

本笔记来自 计算机程序的思维逻辑 系列文章

反射

Class

Class是一个泛型类,有一个类型参数

名称信息

数组元素类型对应表
元素类型 字符表示
类或接口 L
byte B
boolean Z
char C
int I
float F
long J
double D
short S

字段信息

类中定义的静态变量和实例变量都被称为 字段 ,用类Field表示

获取字段信息的方法
Field

方法信息

类中定义的静态方法和实例方法都称为 方法 ,用类Method表示

获取方法信息的方法
Method

创建对象

使用ClassT newInstance()方法创建对象

该方法会调用类的默认构造方法(即无参公共构造方法),如果类没有该构造方法,会抛异常

获取构造方法的方法
Constructor

类型检查和转换

类型信息

声明信息

内部类

数组

Class<?> getComponentType() 获取数组元素类型

Array

数组使用Object而非Object[]表示,是为了方便处理多种类型的数组

枚举

T[] getEnumConstants() 返回枚举常量

泛型

Class

TypeVariable<Class<T>>[] getTypeParameters() 返回类的泛型信息

Field

Type getGenericType() 返回字段的泛型信息

Method
Constructor

Type[] getGenericParameterTypes() 返回构造方法参数的泛型信息

Type

接口

子接口有

注解

创建

@interface

定义注解

@Target

元注解,表示注解的目标;目标可以有多个,用 {} 表示

类型为ElementType,可选值有:

@Retention

表示注解信息保留到什么时候,取值只能有一个

类型为RetentionPolicy,可选值有:

参数

定义的方式是在注解内定义一些方法

参数定义时可以使用 default 指定一个默认值

参数的值不能为 null

当只有一个参数,且名称为 value 时,提供参数值时可以省略 value=

注解内合法的参数类型有

@Inherited

注解不能继承

在注解上声明该元注解,当父类声明了该注解,子类自动拥有该注解

查看注解信息

Annotation

注解本身是一个接口

所有的注解类型,内部实现都是扩展Annotation

动态代理

Java SDK动态代理

使用ProxynewProxyInstance方法创建代理对象

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

InvocationHandler

处理代理类和被代理对象之间的关系和调用实现

Object invoke(Object proxy, Method method, Object[] args)

基本原理

动态生成代理类,继承Proxy,动态创建每个接口的实现代码,即转发给InvocationHandler处理

查看动态生成的代理类文件
java -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true <包含main方法的完整类名>

cglib动态代理

基本原理

动态生成一个类,继承被代理的类,代理类重写了父类的所有 publicfinal 的方法

对比

Java SDK动态代理面向的是一组 接口 ,只能为接口创建代理,返回的代理对象也只能转换到某个接口类型,无法代理一个没有接口的类,也无法代理非接口中定义的方法;而cglib则是面向一个具体的 ,动态创建新类,继承被代理类,重写其方法

类加载机制

类加载的基本机制和过程

Java运行时,会根据类的完全限定名寻找并加载类,寻找的方式基本就是在系统类和指定的类路径中寻找

类加载器

负责加载类的类,输入完全限定的类名,输出Class对象

一般程序运行时,都会有三个

基本过程

这三个类加载器有父子委派关系,子加载器有一个变量 parent 指向父加载器,在子加载器加载时,一般会首先通过父加载器加载

加载一个类时,基本过程:

这个过程一般被称为 双亲委派 模型,即优先让父加载器去加载

一个程序运行时,会创建一个Application ClassLoader,在程序中用到ClassLoader的地方,如果没有指定,一般用的都是它,所以,它也被称为 系统类加载器

ClassLoader

方法
对比

使用ClassLoaderloadClass方法和ClassforName方法都可以加载类,但ClassLoaderloadClass方法不会执行类的初始化代码

应用

上一篇下一篇

猜你喜欢

热点阅读