您的位置:首页 > 编程语言 > Java开发

java反射机制

2016-02-17 09:04 477 查看
class反射机制:

指的是可以于运行时加载,探知和使用编译期间完全未知的类.

程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性;

加载完类之后, 在堆内存中会产生一个
Class
类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个
Class
对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:
反射。


class对象获取:

对象的
getClass()
方法;

类的
.class
(最安全/性能最好)属性;

运用
Class.forName(String className)
动态加载类,
className
需要是类的全限定名(最常用).

从class中获取信息

Class
类提供了大量的实例方法来获取该Class对象所对应的详细信息,Class类大致包含如下方法,其中每个方法都包含多个重载版本,因此我们只是做简单的介绍,详细请参考JDK文档

获取类内信息

获取内容方法签名
构造器
Constructor<T> getConstructor(Class<?>... parameterTypes)
包含的方法
Method getMethod(String name, Class<?>... parameterTypes)
包含的属性
Field getField(String name)
包含的
Annotation
<A extends Annotation> A getAnnotation(Class<A> annotationClass)
内部类
Class<?>[] getDeclaredClasses()
外部类
Class<?> getDeclaringClass()
所实现的接口
Class<?>[] getInterfaces()
修饰符
int getModifiers()
所在包
Package getPackage()
类名
String getName()
简称
String getSimpleName()
一些判断类本身信息的方法

判断内容方法签名
注解类型?
boolean isAnnotation()
使用了该
Annotation
修饰?
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
匿名类?
boolean isAnonymousClass()
数组?
boolean isArray()
枚举?
boolean isEnum()
原始类型?
boolean isPrimitive()
接口?
boolean isInterface()
obj
是否是该
Class
的实例
boolean isInstance(Object obj)
使用反射生成并操作对象:

Method Constructor Field这些类都实现了java.lang.reflect.Member接口,程序可以通过Method对象来执行相应的方法,通过Constructor对象来调用对应的构造器创建实例,通过Filed对象直接访问和修改对象的成员变量值.

创建对象

通过反射来生成对象的方式有两种:

使用
Class
对象的
newInstance()
方法来创建该
Class
对象对应类的实例(这种方式要求该Class对象的对应类有默认构造器).

先使用
Class
对象获取指定的
Constructor
对象, 再调用Constructor对象的
newInstance()
方法来创建该Class对象对应类的实例(通过这种方式可以选择指定的构造器来创建实例).

通过第一种方式来创建对象比较常见, 像Spring这种框架都需要根据配置文件(如
applicationContext.xml
)信息来创建Java对象,从配置文件中读取的只是某个类的全限定名字符串,程序需要根据该字符串来创建对应的实例,就必须使用默认的构造器来反射对象.
下面我们就模拟Spring实现一个简单的对象池, 该对象池会根据文件读取key-value对, 然后创建这些对象, 并放入
Map
中.

经常用到的地方

1.工厂模式:Factory类中用反射的话,添加了一个新的类之后,就不需要再修改工厂类Factory了
2.数据库JDBC中通过Class.forName(Driver).来获得数据库连接驱动

Demo1: 包名: com.wanghongye.reflect,完整类名: com.wanghongye.reflect.Person
===============================================
Demo2:(写法1) 包名: com.wanghongye.reflect,完整类名: com.wanghongye.reflect.Person
Demo2:(写法2) 包名: com.wanghongye.reflect,完整类名: com.wanghongye.reflect.Person
===============================================
Demo3: wanghongye : 20
===============================================
Demo4: wanghongye : 30  ,   wanghongye : 20
===============================================
Demo5: 修改属性之后得到属性变量的值:胖虎先森
===============================================
Demo6:  SuperMan类的父类名: com.wanghongye.reflect.Person
===============================================
类中的成员: private boolean com.wanghongye.reflect.SuperMan.BlueBriefs
===============================================
Demo6,取得SuperMan类的方法:
函数名:fly
函数返回类型:void
函数访问修饰符:public
函数代码写法: public void com.wanghongye.reflect.SuperMan.fly()
Demo6,取得SuperMan类的方法:
函数名:walk
函数返回类型:void
函数访问修饰符:public
函数代码写法: public void com.wanghongye.reflect.SuperMan.walk(int)
Demo6,取得SuperMan类的方法:
函数名:isBlueBriefs
函数返回类型:boolean
函数访问修饰符:public
函数代码写法: public boolean com.wanghongye.reflect.SuperMan.isBlueBriefs()
Demo6,取得SuperMan类的方法:
函数名:setBlueBriefs
函数返回类型:void
函数访问修饰符:public
函数代码写法: public void com.wanghongye.reflect.SuperMan.setBlueBriefs(boolean)
===============================================
实现的接口类名: com.wanghongye.reflect.ActionInterface
===============================================
Demo7:
调用无参方法fly():
超人会飞耶~~
调用有参方法walk(int m):
超人会走耶~~走了100米就走不动了!
===============================================
Demo8: 类加载器类名: sun.misc.Launcher$AppClassLoader
===============================================


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: