反射【Java】
简介
反射是Java语言的一种机制,可以在运行时获取操作对象的具体类型,而且通过类型可以获取类的构造,包括成员变量以及成员方法,并且可以动态的调用这些方法或者改变这些变量的值。
Java一般认为是一门静态语言。静态语言是指编译时就可以确定变量的数据类型的语言,大多数静态语言要求在使用变量之前必须声明数据的类型。常见的静态语言有C、C++、Golang等,Java通常也被认为是静态语言。
PHP、JavaScript、Python、Perl等语言的变量在使用前不需要声明数据类型,在运行时根据被赋值的值类型才确定数据的类型,此类语言称为动态语言。
而通过反射的能力,Java语言可以动态的改变对象的值,甚至可以动态改变数据类型,所以反射使得Java语言具备了动态语言的能力。
Java主要通过Class类来实现反射的能力,JVM在完成一个类的加载过程之后,在堆内存会构造一个Class类型的对象,该对象包含了类完整的构造信息,通过该类可以窥视到Java类的结构,通过Class类可以实例化类的对象,获取类的方法,修改方法的值。
原理
反射是一种“语义同像”,语义同像将程序的一些内部状态,例如对象的属性,对象的方法指针等暴露给程序的运行态,通过这种能力,程序可以在运行时动态修改对象的值。
反射需要存储或者可以关联对象的元信息,因为静态语言在编译时已经可以确定对象的类型,所以这些信息不是运行时的必须信息,为了执行效率,这些信息往往在编译后的信息中剥离,如果要支持反射,就需要存储这些相关的信息。
反射违反了面向对象编程中的封装性。
Java中反射的核心来自Class类。
Class类是描述对象类型信息的类,除了Class类自身之外,所有类都有一个Class类型的对象。
例如A.class经过ClassLoader加载到JVM之后,在方法区会产生一个A.class的对象,这个对象是Class类型的,在范型化也可以表示为Class<A>。
反射API
Class对象是反射实现的关键,通过Class对象可以获取对象的属性以及方法。
获取Class
Java语言中获取 Class 类对象的方法一般如下三种。
- 使用Class.forName可以加载ClassPath路径下的类,在加载jdbc驱动程序的时候经常采用该方式。
Class clazz = Class.forName("oracle.jdbc.driver.OracleDriver")
- 通过.class可以获得已经加载到JVM的类
Class clazz = String.class;
使用对象的getClass()方法可以获取该对象的Class,该方法继承自Object.class。
Class clazz = obj.getClass();
获取属性/方法/构造器
Modifier and Type | Method and Description |
---|---|
<U> Class<? extends U>
|
asSubclass(Class<U> clazz)
Casts this |
T
|
cast(Object obj)
Casts an object to the class or interface represented by this |
boolean
|
desiredAssertionStatus()
Returns the assertion status that would be assigned to this class if it were to be initialized at the time this method is invoked. |
static Class<?>
|
forName(String className)
Returns the |
static Class<?>
|
forName(String name, boolean initialize, ClassLoader loader)
Returns the |
AnnotatedType[]
|
getAnnotatedInterfaces()
Returns an array of |
AnnotatedType
|
getAnnotatedSuperclass()
Returns an |
<A extends Annotation> A
|
getAnnotation(Class<A> annotationClass)
Returns this element's annotation for the specified type if such an annotation is present, else null. |
Annotation[]
|
getAnnotations()
Returns annotations that are present on this element. |
<A extends Annotation> A[]
|
getAnnotationsByType(Class<A> annotationClass)
Returns annotations that are associated with this element. |
String
|
getCanonicalName()
Returns the canonical name of the underlying class as defined by the Java Language Specification. |
Class<?>[]
|
getClasses()
Returns an array containing |
ClassLoader
|
getClassLoader()
Returns the class loader for the class. |
Class<?>
|
getComponentType()
Returns the |
Constructor<T>
|
getConstructor(Class<?>... parameterTypes)
Returns a |
Constructor<?>[]
|
getConstructors()
Returns an array containing |
<A extends Annotation> A
|
getDeclaredAnnotation(Class<A> annotationClass)
Returns this element's annotation for the specified type if such an annotation is directly present, else null. |
Annotation[]
|
getDeclaredAnnotations()
Returns annotations that are directly present on this element. |
<A extends Annotation> A[]
|
getDeclaredAnnotationsByType(Class<A> annotationClass)
Returns this element's annotation(s) for the specified type if such annotations are either directly present or indirectly present. |
Class<?>[]
|
getDeclaredClasses()
Returns an array of |
Constructor<T>
|
getDeclaredConstructor(Class<?>... parameterTypes)
Returns a |
Constructor<?>[]
|
getDeclaredConstructors()
Returns an array of |
Field
|
getDeclaredField(String name)
Returns a |
Field[]
|
getDeclaredFields()
Returns an array of |
Method
|
getDeclaredMethod(String name, Class<?>... parameterTypes)
Returns a |
Method[]
|
getDeclaredMethods()
Returns an array containing |
Class<?>
|
getDeclaringClass()
If the class or interface represented by this |
Class<?>
|
getEnclosingClass()
Returns the immediately enclosing class of the underlying class. |
Constructor<?>
|
getEnclosingConstructor()
If this |
Method
|
getEnclosingMethod()
If this |
T[]
|
getEnumConstants()
Returns the elements of this enum class or null if this Class object does not represent an enum type. |
Field
|
getField(String name)
Returns a |
Field[]
|
getFields()
Returns an array containing |
Type[]
|
getGenericInterfaces()
Returns the |
Type
|
getGenericSuperclass()
Returns the |
Class<?>[]
|
getInterfaces()
Determines the interfaces implemented by the class or interface represented by this object. |
Method
|
getMethod(String name, Class<?>... parameterTypes)
Returns a |
Method[]
|
getMethods()
Returns an array containing |
int
|
getModifiers()
Returns the Java language modifiers for this class or interface, encoded in an integer. |
String
|
getName()
Returns the name of the entity (class, interface, array class, primitive type, or void) represented by this |
Package
|
getPackage()
Gets the package for this class. |
ProtectionDomain
|
getProtectionDomain()
Returns the |
URL
|
getResource(String name)
Finds a resource with a given name. |
InputStream
|
getResourceAsStream(String name)
Finds a resource with a given name. |
Object[]
|
getSigners()
Gets the signers of this class. |
String
|
getSimpleName()
Returns the simple name of the underlying class as given in the source code. |
Class<? super T>
|
getSuperclass()
Returns the |
String
|
getTypeName()
Return an informative string for the name of this type. |
TypeVariable<Class<T>>[]
|
getTypeParameters()
Returns an array of |
boolean
|
isAnnotation()
Returns true if this |
boolean
|
isAnnotationPresent(Class<? extends Annotation> annotationClass)
Returns true if an annotation for the specified type is present on this element, else false. |
boolean
|
isAnonymousClass()
Returns |
boolean
|
isArray()
Determines if this |
boolean
|
isAssignableFrom(Class<?> cls)
Determines if the class or interface represented by this |
boolean
|
isEnum()
Returns true if and only if this class was declared as an enum in the source code. |
boolean
|
isInstance(Object obj)
Determines if the specified |
boolean
|
isInterface()
Determines if the specified |
boolean
|
isLocalClass()
Returns |
boolean
|
isMemberClass()
Returns |
boolean
|
isPrimitive()
Determines if the specified |
boolean
|
isSynthetic()
Returns |
T
|
newInstance()
Creates a new instance of the class represented by this |
String
|
toGenericString()
Returns a string describing this |
String
|
toString()
Converts the object to a string. |