Java反射机制主要提供了以下功能: (伟大的作用)
1 在运行时判断任意一个对象所属的类;
2 在运行时构造任意一个类的对象;
3 在运行时判断任意一个类所具有的成员变量和方法;
4 在运行时调用任意一个对象的方法;
5 生成动态代理。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。
每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
1 如何得到Class的对象呢?有三种方法可以的获取:
1、调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。 例如:MyObject x;
Class c1 = x.getClass();
2、使用Class类的中静态forName()方法获得与字符串对应的Class对象。 例如:
Class c2=Class.forName("MyObject"),Employee必须是接口或者类的名字。
3、获取Class类型对象的第三个方法非常简单。如果T是一个Java类型,那么T.class就代表了匹配的类对象。 例如
Class cl1 = Manager.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
(一句话):对象用.getClass,类用.class,
2 Class类的常用方法
1 、getName()一个Class对象描述了一个特定类的属性,Class类中最常用的方法getName以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
Class还有一个有用的方法可以为类创建一个实例,这个方法叫做newInstance()。例如:
x.getClass.newInstance(),创建了一个同x一样类型的新实例。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。
返回该类的类加载器。
返回表示数组组件类型的 Class。
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
判定此 Class 对象是否表示一个数组类
Constructor getConstructor(Class[] params) --
获得使用特殊的参数类型的公共构造函数,
Constructor[] getConstructors() --
获得类的所有公共构造函数
Constructor
getDeclaredConstructor(Class[]
params)
--
获得使用特定参数类型的构造函数
(
与
接入级别无关
)
Constructor[] getDeclaredConstructors() --
获得类的所有构造函数
(
与接入级别无关
)
获得字段信息的
Class
反射调用不同于那些用于接入构造函数的调用,
在参数类型数组中使
用了字段名:
Field getField(String name) --
获得命名的公共字段
Field[] getFields() --
获得类的所有公共字段
Field getDeclaredField(String name) --
获得类声明的命名的字段
Field[] getDeclaredFields() --
获得类声明的所有字段
用于获得方法信息函数:
Method getMethod(String name, Class[] params) --
使用特定的参数类型,获得命名的公共方
法
Method[] getMethods() --
获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params) --
使用特写的参数类型,
获得类声明
3.4父类
通过Class
对象可以获取类的父类
,如下:
Class aClass = MyObject.class;
Class superclass = aClass.getSuperclass();
父类的Class对象和其它Class对象一样是一个Class对象,可以继续使用反射.
3.5实现的接口
通过给定的类可以获取这个类所实现的接口列表,如下:
Class aClass = MyObject.class;
Class[] interfaces = aClass.getInterfaces();
一个类可以实现多个接口。因此返回一个Class数组。在Java反射机制中,接口也由Class对象表示。
注意:只有给定类声明实现的接口才会返回。例如,如果类A的父类B实现了一个接口C,但类A并没有声明它也实现了C,那么C不会被返回到数组中。即使类A实际上实现了接口C,因为它的父类B实现了C。
为了得到一个给定的类实现接口的完整列表,需要递归访问类和其超类。
3.6构造函数
使用Class对象可以获取类的构造函数,如下:
Class aClass = MyObject.class;
Constructor[] constructors = aClass.getConstructors();
3.7方法
使用Class对象可以获取类的方法,如下:
Class aClass = MyObject.class;
Method[] methods = aClass.getMethods();
关于方法更详细信息参见方法这节.
3.8字段
使用Class对象可以获取类的字段(成员变量),如下:
Class aClass = MyObject.class;
Field[] fields = aClass.getFields();
关于字段更详细信息参见 字段这节.
3.9注解
使用Class对象可以获取类的注解,如下:
Class aClass = MyObject.class;
Annotation[] annotations = aClass.getAnnotations();
关于注解更详细信息参见注解这节.
4. 构造函数
使用Java反射可以在运行时检查类的构造函数并实例化对象。这是通过Java类java.lang.reflect.Constructor来实现的。以下是Java Construcor对象的更多细节:
(1) 获取Constructor对象
(2) 构造函数参数
(3) 使用Constructor对象实例化对象
4.1获取Constructor对象
Constructor
类是从Class对象获取的,举例:
Class aClass = MyObject.class;
Constructor[] constructors = aClass.getConstructors();
Constructor
数组为每一个在类中声明的
public
构造函数保存一个
Constructor
实例
。
如果知道要访问的构造函数确切的参数类型,可以不获取构造函数数组。本示例将返回给定类中接受一个字符串作为参数的公共构造函数。
Class aClass = MyObject.class;//MyObject有一个参数为字符串的公共构造函数
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
如果没有匹配给定的构造函数参数,在这个例子当中是String.class
,会抛出 NoSuchMethodException
异常.
4.2构造函数参数
可以知道给定的构造函数接受什么参数,如下:
Class aClass = MyObject.class;//MyObject有一个参数为字符串的公共构造函数
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
Class[] parameterTypes = constructor.getParameterTypes();
4.3使用Constructor对象实例化对象
可以像这样实例化对象:
//获取使用字符串作为参数的constructor
Constructor constructor = MyObject.class.getConstructor(String.class);
MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");
Constructor.newInstance()
方法使用可变长度的参数,但是在调用构造函数时必须为每一个参数提供一个准确的参量.在这个例子中构造函数接受一个字符串作为参数,所以必须要提供一个字符串。
5. 字段
使用Java反射你可以在运行时检查类的字段(成员变量)并 get / set它们.这是通过Java类java.lang.reflect.Field
来完成的
.以下是JavaField
对象更多细节:
(1) 获取Field 对象
(2) 字段名称
(3) 字段类型
5.1获取Field 对象
Field
类是从Class
对象获取的.举例:
Class aClass = MyObject.class;
Field[] methods = aClass.getFields();
Field
数组为类中声明的每一个
public
字段
保存一个
Field
实例。
如果知道要访问的字段名称,可以这样获取它:
Class aClass = MyObject.class
Field field = aClass.getField("someField");
根据下面 MyObject
声明的someField
字段,
以上的例子将返回Field
实例:
public class MyObject{
public String someField = null;
}
如果不存在getField()方法中所给参数名字对应的字段,会抛出NoSuchFieldException
异常
.
5.2字段名称
一旦获得一个 Field
实例,可以使用Field.getName()
方法获取它的字段名字,
如下:
5.3字段类型
你可以使用Field.getType()
方法确定一个字段的类型
(
String,int等)
:
5.4获取和设置字段值
一旦获得一个Field引用,可以使用Field.get()
和 Field.set()
方法获取和设置
它的值,如下:
Class aClass = MyObject.class
Field field = aClass.getField("someField");
MyObject objectInstance = new MyObject();
Object value = field.get(objectInstance);
field.set(objetInstance, value);
传递给get和set方法的对象实例参数应该是拥有该字段的类的一个实例。在上述的例子中使用了MyObject的一个实例,因为someField是MyObject类的一个实例成员。静态字段(public static)给get和set方法传递null作为参数,而不是以上传递的objectInstance参数。
6. 方法
使用Java反射你可以在运行时检查类的方法并调用它们.这是通过Java类java.lang.reflect.Method
来实现的
.本章将会更详细的介绍 Java Method
对象.下面是本章所涵盖的主题:
(1) 获取 Method对象
(2) 方法的参数和返回值类型
(3) 使用Method对象调用方法
6.1获取Method对象
Method
类是从 Class
对象中获取的.举例:
Class aClass = MyObject.class;
Method[] methods = aClass.getMethods();
Method
数组将为类中声明的每一个
public
的方法保存一个
Method
实例
.
如果你知道要访问方法的确切的参数类型,可以不必获取方法数组。本示例返回给定类中接受一个字符串作为参数的公共方法”doSomething”。
Class aClass = MyObject.class;
Method method = aClass.getMethod("doSomething", new Class[]{String.class});
如果没有方法匹配所给的方法名和参数,在这个例子中是String.class
,将抛出NoSuchMethodException
异常.
如果你想访问的方法没有参数,传递 null
作为参数类型数组,如下:
6.2方法的参数和返回值类型
使用Method对象可以获取方法的参数,如下:
Method method = ... //获取 method – 如上
Class[] parameterTypes = method.getParameterTypes();
亦可以获取方法的返回值类型,如下:
6.3使用Method对象调用方法
可以像这样调用方法:
//get method that takes a String as argument
Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(null, "parameter-value1");
空参数是你想要调用该方法的对象。如果该方法是静态的,使用null,而不是一个对象实例。在这个例子中,如果doSomething(String.class)不是静态的,你需要提供有效的MyObject实例而不是null作为参数;
Method.invoke(Object target, Object ...parameters)
方法接受可变长度的参数,但是你在调用时必须为每一个参数提供一个准确的参量。在这个例子中,方法以字符串作为参数的,所以必须提供一个字符串。
//来自http://blog.youkuaiyun.com/jackiehff/article/details/8509075博客:
此博客写的非常好!
我只是载录一下对自己有用的!!