反射的概述
Reflection 是被视为动态语言的关键,反射机制允许程序在执行期间,借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性和方法。
加载完类后,产生一个class 类型的对象,包含完整的类的结果信息。
这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射
动态语言:Object - C , C #, JavaScript , PHP, Pyehon ,
静态语言:Java , C , C ++
Java 反射机制提供的功能:
1. 运行时判断任意一个对象所属的类
2. 运行时构造任意一个类的对象
3. 运行时判断任意一个类所具有的成员变量和方法
4. 在运行时获取泛型信息
5. 在运行时调用任意一个对象的成员变量和方法
6. 在运行时处理注解
7. 生产动态代理
反射相关的主要API
1. java. lang. Class: 代表一个类
2. java. lang. reflect. Method: 代表类的方法
3. java. lang. reflect. Field: 代表类的成员变量
4. java. lang. reflect. Constructor: 代表类的构造器
关于java. lang. Class 类的理解
1. 类的加载过程:
程序经过javac. exe命令以后,会生成一个或多个字节码文件( . class 结尾) 。
接着我们使用java. exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件
加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此
运行时类,就作为Class 的一个实例。
2. 换句话说,Class 的实例就对应着一个运行时类。
3. 加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式
来获取此运行时类。
疑问1 :通过直接new 的方式或反射的方式都可以调用公共的结构,开发中到底用那个?
建议:直接new 的方式。
什么时候会使用:反射的方式。 反射的特征:动态性
疑问2 :反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?
不矛盾。
封装性:是建议你哪些结构可以调用,哪些结构不需要调用
反射:是需要需要调用哪些结构
此文章所有类的为
@MyAnnotation ( value= "hi" )
public class Person extends Creature < String > implements Comparable < String > , MyInterface {
private String name;
int age;
public int id;
public Person ( ) { }
@MyAnnotation ( value= "abc" )
private Person ( String name) {
this . name = name;
}
Person ( String name, int age) {
this . name = name;
this . age = age;
}
@MyAnnotation
private String show ( String nation) {
System . out. println ( "我的国籍是:" + nation) ;
return nation;
}
public String display ( String interests, int age) throws NullPointerException , ClassCastException {
return interests + age;
}
@Override
public void info ( ) {
System . out. println ( "我是一个人" ) ;
}
@Override
public int compareTo ( String o) {
return 0 ;
}
private static void showDesc ( ) {
System . out. println ( "我是一个可爱的人" ) ;
}
@Override
public String toString ( ) {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}' ;
}
}
public interface MyInterface {
void info ( ) ;
}
@Target ( { TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE} )
@Retention ( RetentionPolicy . RUNTIME)
public @interface MyAnnotation {
String value ( ) default "hello" ;
}
public class Creature < T > implements Serializable {
private char gender;
public double weight;
private void breath ( ) {
System . out. println ( "生物呼吸" ) ;
}
public void eat ( ) {
System . out. println ( "生物吃东西" ) ;
}
}
通过反射创建对象:可以调用私有的构造器
Class < Person > clazz = Person . class ;
Constructor < Person > cons = clazz. getDeclaredConstructor ( String . class , int . class ) ;
cons. setAccessible ( true ) ;
Object obj = cons. newInstance ( "Tom" , 12 ) ;
System . out. println ( obj. toString ( ) ) ;
Person p = ( Person ) obj;
System . out. println ( p) ;
通过反射使用类中的方法和属性:可以设置和使用私有的属性和方法
Class < Person > clazz = Person . class ;
Constructor < Person > cons = clazz. getDeclaredConstructor ( String . class , int . class ) ;
cons. setAccessible ( true ) ;
Object obj = cons. newInstance ( "Tom" , 12 ) ;
System . out. println ( obj. toString ( ) ) ;
Person p = ( Person ) obj;
System . out. println ( p) ;
Field age = clazz. getDeclareField ( "age" ) ;
age. setAccessible ( true ) ;
age. set ( p, 10 ) ;
System . out. println ( p) ;
Method show = clazz. getDeclaredMethod ( "show" , String . class ) ;
show. setAccessible ( true ) ;
show. invoke ( p, "中国" ) ;
通过反射获取class实例的四种方式
Class < Person > clazz = Person . class ;
System . out. println ( clazz) ;
Person p1 = new Person ( ) ;
Class clazz2 = p1. getClass ( ) ;
System . out. println ( clazz2) ;
Class < ? > clazz3 = Class . forName ( "Person" ) ;
System . out. println ( clazz3) ;
System . out. println ( clazz == clazz2) ;
System . out. println ( clazz == clazz3) ;
ClassLoader classLoader = reflection. class . getClassLoader ( ) ;
Class < ? > clazz4 = classLoader. loadClass ( "Person" ) ;
System . out. println ( clazz4) ;
系统类加载器、拓展类加载器、引导类加载器的了解
ClassLoader classLoader = reflection. class . getClassLoader ( ) ;
System . out. println ( classLoader) ;
ClassLoader parent = classLoader. getParent ( ) ;
System . out. println ( parent) ;
ClassLoader parent1 = parent. getParent ( ) ;
System . out. println ( parent1) ;
读取配置Properties文件的的方法
Properties pro = new Properties ( ) ;
FileInputStream fis = new FileInputStream ( "jdbc.properties" ) ;
pro. load ( fis) ;
String user = pro. getProperty ( "user" ) ;
String password = pro. getProperty ( "password" ) ;
System . out. println ( user + " password" + password) ;
ClassLoader classLoader = reflection. class . getClassLoader ( ) ;
InputStream is = classLoader. getResourceAsStream ( "jdbc1.properties" ) ;
pro. load ( is) ;
String user1 = pro. getProperty ( "user" ) ;
String password1 = pro. getProperty ( "password" ) ;
System . out. println ( user1 + " password" + password1) ;
通过实例体会反射的动态性
for ( int i = 0 ; i < 100 ; i++ ) {
int num = new Random ( ) . nextInt ( 3 ) ;
String classPath = "" ;
switch ( num) {
case 0 :
classPath = "java.util.Date" ;
break ;
case 1 :
classPath = "java.lang.Object" ;
break ;
case 2 :
classPath = "Person" ;
break ;
}
try {
Object obj = getInstance ( classPath) ;
System . out. println ( obj) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public Object getInstance ( String classPath) throws Exception {
Class clazz = Class . forName ( classPath) ;
return clazz. newInstance ( ) ;
}
getFields()获取public的属性 vs getDeclareFields()获取所有的属性
Class < java1. Person> clazz = java1. Person. class ;
Field [ ] field = clazz. getFields ( ) ;
for ( Field f :
field) {
System . out. println ( f) ;
}
Field [ ] declaredFields = clazz. getDeclaredFields ( ) ;
for ( Field f :
declaredFields) {
System . out. println ( f) ;
}
获取具体的结构:getModifiers()权限修饰符,getType()数据类型,getName()变量名
Class < Person > clazz = Person . class ;
Field [ ] declaredFields = clazz. getDeclaredFields ( ) ;
for ( Field f: declaredFields) {
int modifiers = f. getModifiers ( ) ;
System . out. println ( Modifier . toString ( modifiers) ) ;
Class < ? > type = f. getType ( ) ;
System . out. println ( type. getName ( ) + "\t" ) ;
String name = f. getName ( ) ;
System . out. println ( name) ;
}
获取方法体 和 构造器体
Class < java1. Person> clazz = java1. Person. class ;
Method [ ] methods = clazz. getMethods ( ) ;
for ( Method m : methods) {
System . out. println ( m) ;
}
System . out. println ( "____________________________________" ) ;
Method [ ] declaredMethods = clazz. getDeclaredMethods ( ) ;
for ( Method m : declaredMethods) {
System . out. println ( m) ;
}
System . out. println ( "**********************************" ) ;
Constructor [ ] constructors = clazz. getConstructors ( ) ;
for ( Constructor c : constructors) {
System . out. println ( c) ;
}
System . out. println ( "**********************************" ) ;
Constructor [ ] declaredConstructors = clazz. getDeclaredConstructors ( ) ;
for ( Constructor c : declaredConstructors) {
System . out. println ( c) ;
}
获取运行时,方法的所有修饰
Class < java1. Person> clazz = java1. Person. class ;
Method [ ] declaredMethods = clazz. getDeclaredMethods ( ) ;
for ( Method m : declaredMethods) {
Annotation [ ] annos = m. getAnnotations ( ) ;
for ( Annotation a : annos) {
System . out. println ( a) ;
}
System . out. print ( Modifier . toString ( m. getModifiers ( ) ) + "\t" ) ;
System . out. print ( m. getReturnType ( ) . getName ( ) + "\t" ) ;
System . out. print ( m. getName ( ) ) ;
System . out. print ( "(" ) ;
Class [ ] parameterTypes = m. getParameterTypes ( ) ;
if ( ! ( parameterTypes == null && parameterTypes. length == 0 ) ) {
for ( int i = 0 ; i < parameterTypes. length; i++ ) {
if ( i == parameterTypes. length - 1 ) {
System . out. print ( parameterTypes[ i] . getName ( ) + " args_" + i) ;
break ;
}
System . out. print ( parameterTypes[ i] . getName ( ) + " args_" + i + "," ) ;
}
}
System . out. print ( ")" ) ;
Class [ ] exceptionTypes = m. getExceptionTypes ( ) ;
if ( exceptionTypes. length > 0 ) {
System . out. print ( "throws " ) ;
for ( int i = 0 ; i < exceptionTypes. length; i++ ) {
if ( i == exceptionTypes. length - 1 ) {
System . out. print ( exceptionTypes[ i] . getName ( ) ) ;
break ;
}
System . out. print ( exceptionTypes[ i] . getName ( ) + "," ) ;
}
}
System . out. println ( ) ;
}
获取父类,带泛型的父类,父类的泛型
@Test
public void test18 ( ) {
Class < java1. Person> clazz = java1. Person. class ;
Class superclass = clazz. getSuperclass ( ) ;
System . out. println ( superclass) ;
}
@Test
public void test19 ( ) {
Class < java1. Person> clazz = java1. Person. class ;
Type genericSuperclass = clazz. getGenericSuperclass ( ) ;
System . out. println ( genericSuperclass) ;
}
@Test
public void test20 ( ) {
Class < Person > clazz = java1. Person. class ;
Type genericSuperclass = clazz. getGenericSuperclass ( ) ;
ParameterizedType paramType = ( ParameterizedType ) genericSuperclass;
Type [ ] actualTypeArguments = paramType. getActualTypeArguments ( ) ;
System . out. println ( ( ( Class ) actualTypeArguments[ 0 ] ) . getName ( ) ) ;
}
获取接口
@Test
public void test21 ( ) {
Class < java1. Person> clazz = java1. Person. class ;
Class [ ] interfaces = clazz. getInterfaces ( ) ;
for ( Class c : interfaces) {
System . out. println ( c) ;
}
System . out. println ( ) ;
Class [ ] interfaces1 = clazz. getSuperclass ( ) . getInterfaces ( ) ;
for ( Class c : interfaces1) {
System . out. println ( c) ;
}
}
获取运行时类所在的包
@Test
public void test24 ( ) {
Class < java1. Person> clazz = java1. Person. class ;
Package pack = clazz. getPackage ( ) ;
System . out. println ( pack) ;
}
获取类的注解
public void test25 ( ) {
Class < java1. Person> clazz = java1. Person. class ;
Annotation [ ] annotations = clazz. getAnnotations ( ) ;
for ( Annotation annos : annotations) {
System . out. println ( annos) ;
}
}
通过反射调用静态方法:invoke(null)
@Test
public void test2425 ( ) throws Exception {
Class < java1. Person> clazz = java1. Person. class ;
java1. Person p = ( java1. Person) clazz. newInstance ( ) ;
Method show = clazz. getDeclaredMethod ( "show" , String . class ) ;
show. setAccessible ( true ) ;
Object chn = show. invoke ( p, "CHN" ) ;
System . out. println ( chn) ;
System . out. println ( "**********如何调用静态方法" ) ;
Method showDesc = clazz. getDeclaredMethod ( "showDesc" ) ;
showDesc. setAccessible ( true ) ;
Object invoke = showDesc. invoke ( null ) ;
System . out. println ( invoke) ;
}