JavaSE-反射、注解、断言


反射(Reflection)

反射是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

  • java.lang.Class:代表一个类
  • java.lang.reflect.Constructor:构造器
  • java.lang.reflect.Field:成员变量
  • java.lang.reflect.Method:方法

加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构

  • 一个类在内存中只有一个Class对象
  • 一个类被加载后,类的整个结构都会被封装在Class对象中

获取反射对象

反射的第一步都是先得到编译后的Class类对象,然后就可以得到Class的全部成分

获取CLass对象的方法

  • 若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高 Class clazz = Person.class;
    • 类:Object.class 或者 Class.class
    • 接口:Comparable.class
    • 数组:String[].class 或者 int[][].class
    • 枚举:Override.class
    • 注解:ElementType.class
    • 基本数据类型:Integer.class
    • void空类型:void.class
  • 已知某个类的实例,调用该实例的Object类的getClass()方法获取Class对象
    • Class clazz = person.getClass();
  • 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()方法获取,可能抛出ClassNotFoundException异常
    • Class clazz = Class.forName("com.demo.pojo.Person");
  • 内置基本数据类型可以直接用类名.Type
  • 利用ClassLoader
Class类常用方法
常用方法 返回值类型 说明
newInstance() T 创建由此类对象表示的类的新实例
forName(String className) static Class
forName(String name,boolean initialize,ClassLoader loader) static Class
getClassLoader() ClassLoader
asSubclass(Class clazz) Class
getComponentType() Class
getDeclaringClass() Class
getEnclosingClass() Class
getSuperclass() Class 返回该Class对象对应类的超类的Class对象
getInterfaces() Class[] 返回该Class对象对应类所实现的全部接口
getClasses() class[]
getDeclaredClasses() Class[] 返回该Class对象对应类所在的外部类
getConstructors() Constructor[] 返回所有构造器对象的数组(只能拿public的)
getDeclaredConstructors() Constructor[] 返回所有构造器对象的数组,存在就能拿到
getConstructor(class... parameterTypes) Constructor 返回单个构造器对象(只能拿public的)
getDeclaredConstructor(Class... parameterTypes) Constructor 返回单个构造器对象,存在就能拿到
getEnclosingConstructor() Constructor
getFields() Field[] 返回所有成员变量对象的数组(只能拿public的)
getDeclaredFields() Field[] 返回所有成员变量对象的数组,存在就能拿到
getField(String name) Field 返回单个成员变量对象(只能拿public的)
getDeclaredField(String name) Field 返回单个成员变量对象,存在就能拿到
getMethods() Method[] 返回所有成员方法对象的数组(只能拿public的)
getDeclaredMethods() Method[] 返回所有成员方法对象的数组,存在就能拿到
getMethod(String name,class... parameterTypes) Method 返回单个成员方法对象(只能拿public的)
getDeclaredMethod(String name,class... parameterTypes) Method 返回单个成员方法对象,存在就能拿到
getEnclosingMethod() Method
getAnnotations() Annotation[]
getDeclaredAnnotations() Annotation[]
getAnnotation(Class annotationClass) A
getDeclaredAnnotation(class annotationClass) A
getAnnotatedInterfaces() AnnotatedType[]
getAnnotatedSuperclass() AnnotatedType
getAnnotationsByType(Class annotationClass) A[]
getDeclaredAnnotationsByType(class annotationClass) A[]
getTypeName() String
getTypeParameters() TypeVariable[]
getGenericInterfaces() Type[]
getGenericSuperclass() Type
getName() String 以字符串形式返回此Class对象所表示的类的名称
getSimpleName() String 以字符串形式返回此Class对象所表示类的简称
getCanonicalName() String
getModifiers() int 返回此类的所有修饰符;由public/protected/private/final/static/abstract组成
getPackage() Package 获取此类的包
getResource(String name) URL 查找具有给定名称的资源
getResourceAsStream(String name) InputStream 查找具有给定名称的资源
getProtectionDomain() ProtectionDomain
getSigners() Object[] 获得这个类的签名者
getEnumConstants() T[]
cast(Object obj) T
desiredAssertionStatus() boolean
isAnnotation() boolean 判断是否表示一个注解类型
isAnnotationPresent(class annotationClass) boolean 判断此Class对象是否使用了Annotation修饰
isAnonymousClass() boolean 返回此Class对象是否是一个匿名类
isArray() boolean 判断此Class对象是否是一个数组类
isAssignableFrom(class cls) boolean 判断此Class对象是否是一个匿名类
isEnum() boolean 判断此Class对象是否是一个枚举
isInterface() boolean 判断此Class对象是否是一个接口
isInstance(Object obj) boolean 判断obj是否是此Class对象的实例
isLocalClass() boolean 判断此Class对象是否是一个本地类
isMemberClass() boolean 判断此Class对象是否是一个成员类
isPrimitive() boolean 判断此Class对象是否是一个基本类型
isSynthetic() boolean 判断此Class对象是否是一个合成类
toGenericString() String 返回描述此类的字符串,包括有关修饰符和类型参数的信息
toString() String 将对象转换为字符串
Constructor常用方法
常用方法 返回值类型 说明
equals(Object obj) boolean
getAnnotatedReceiverType() AnnotatedType
getAnnotatedReturnType() AnnotatedType
getAnnotation(Class annotationClass) T
getDeclaredAnnotations() Annotation[]
getDeclaringClass() Class
getExceptionTypes() Class[]
getGenericExceptionTypes() Type[]
getGenericParameterTypes() Type[]
getModifiers() int
getName() String
getParameterAnnotations() Annotation[][]
getParameterCount() int
getParameterTypes() Class[]
getTypeParameters() TypeVariable[]
hashCode() int
isSynthetic() boolean
isVarArgs() boolean
newInstance(Object... initargs) T
toGenericString() String
toString() String
Field常用方法
常用方法 返回值类型 说明
equals(Object obj) boolean
get(Object obj) Object
getAnnotatedType() AnnotatedType
getAnnotation(Class annotationClass) T
getAnnotationsByType(Class annotationClass) T[]
getBoolean(Object obj) boolean
getByte(Object obj) byte
getChar(Object obj) char
getDeclaredAnnotations() Annotation[]
getDeclaringClass() Class
getDouble(Object obj) double
getFloat(Object obj) float
getGenericType() Type
getInt(Object obj) int
getLong(Object obj) long
getModifiers() int
getName() String
getShort(Object obj) short
getType() Class
hashCode() int
isEnumConstant() boolean
isSynthetic() boolean
set(Object obj,Object value) void
setBoolean(Object obj,boolean z) void
setByte(Object obj,byte b) void
setChar(Object obj,char c) void
setDouble(Object obj,double d) void
setFloat(Object obj,float f) void
setInt(Object obj,int i) void
setLong(Object obj,long l) void
setShort(Object obj,short s) void
toGenericString() String
toString() String
Method常用方法
常用方法 返回值类型 说明
equals(Object obj) boolean
getAnnotatedReturnType() AnnotatedType
getAnnotation(Class annotationClass) T
getDeclaredAnnotations() Annotation[]
getDeclaringClass() Class
getDefaultValue() Object
getExceptionTypes() Class[]
getGenericExceptionTypes() Type[]
getGenericParameterTypes() Type[]
getGenericReturnType() Type
getModifiers() int
getName() String
getParameterAnnotations() Annotation[][]
getParameterCount() int
getParameterTypes() Class[]
getReturnType() Class
getTypeParameters() TypeVariable[]
hashCode() int
invoke(Object obj, Object... args) Object
isBridge() boolean
isDefault() boolean
isSynthetic() boolean
isVarArgs() boolean
toGenericString() String
toString() String

注解(Annotation)

注解是从JDK5开始引入的新技术,Java增加了对元数据的支持,也就是Annotation.注解其实是代码里的特殊标记,这些标记可以在编译、类加载、运行时被其他程序(比如编译器等)读取,并执行相应的处理.通过使用注解,程序开发人员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息.从某些方面来看,Annotation就像修饰符一样,可用于修饰包/类/构造器/方法/成员变量/参数/局部变量的声明,这些信息被存储在Annotation的"name=value"对中,然后可以通过反射机制编程实现对这些元数据的访问

基本注解

Java提供了5个基本的注解,这5个基本注解都定义在java.lang包下

基本注解 说明
@Override 重写父类方法;告诉编译器检查这个方法,保证父类要包含一个被该方法重写的方法,否则就会编译出错
@Deprecated 已过时;用于表示某个类/方法已过时,编译器会给出警告
@SuppressWarnings 抑制编译器警告;表示取消显式指定的编译器警告,可用于该程序元素的所有子元素
@SafeVarargs 抑制堆污染警告;泛型擦除时,把一个不带泛型的对象赋值给一个带泛型的变量,就会发生堆污染
@FunctionalInterface 函数式接口;如果接口中只有一个抽象方法,该接口就是函数式接口(可以包含多个默认方法或静态方法)
  • @SuppressWarnings("all")
  • @SuppressWarnings("unchecked")
  • @SuppressWarnings(value={"unchecked","deprecation"})

元注解

Java在java.lang.annotation包下提供了6个元注解(meta annotation)

元注解 说明
@Target 约束自定义注解只能在哪些地方使用
@Retention 申明注解的声明周期
@Documented 指定该注解类将被javadoc工具提取成文档
@Inherited 指定被它修饰的注解类将具有继承性;如果某个类使用了@XXX注解修饰,则其子类将自动被@XXX修饰
@
@Repeatable 重复注解(JDK8)
@Target详解
public @interface Target {
    ElementType[] value();
}
@Target支持的值 说明
ElementType.TYPE 类/接口
ElementType.CONSTRUCTOR 构造器
ElementType.FIELD 成员变量
ElementType.LOCAL_VARIABLE 局部变量
ElementType.METHOD 成员方法
ElementType.PARAMETER 方法参数
ElementType.PACKAGE 包定义
ElementType.ANNOTATION_TYPE 只能修饰Annotation
@Retention详解
public @interface Retention {
    RetentionPolicy value();
}
@Retention支持的值 说明
RetentionPolicy.CLASS 注解只作用在源码阶段,生成的字节码文件中不存在注解
RetentionPolicy.RUNTIME [默认值]注解作用在源码阶段/字节码文件阶段,运行阶段不存在注解
RetentionPolicy.SOURCE [开发常用]注解作用在源码阶段,字节码文件阶段,运行阶段
@Documented详解
public @interface Documented {
}
@Inherited详解
public @interface Inherited {
}

自定义注解

注解可用于修饰任何程序元素,包括类/接口/方法等

  • value属性(特殊属性):如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写
  • 但是如果有多个属性, 且多个属性没有默认值,那么value名称是不能省略的
  • 如果没有默认值,就必须给注解赋值
public @interface 注解名{
    public 属性类型 属性名() default 默认值;
}
public @interface MyTag {
    String name() default "admin";
    int age() default 18;
    String value();
}

提取Annotation信息

断言

断言机制允许在测试期间向代码中插入一些检查语句.当代码发布时,这些输入的检测语句将会被自动地移走.断言失败是致命的,不可回复的错误.断言检查只用于开发和测试阶段
Java引入了 assert 关键字,assert使用语法:

  • assert 条件; // 如果条件判断为true,程序继续执行;如果条件判断为false,则会终止程序并报出AssertionError异常
  • assert 条件:表达式; // 如果条件判断为true,程序继续执行;如果条件判断为false,则会终止程序并报出你所输入的错误信息