------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
注意:反射是在运行的时候进行的,不是在编译的时候运行的。
1 反射的功能
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;生成动态代理。
2 API简介
— java.lang.Class; 代表一个类
— java.lang.reflect.Constructor; 代表类的构造方法
— java.lang.reflect.Field; 代表类的成员变量(成员变量也称为类的属性)
— java.lang.reflect.Method; 代表类的方法
— java.lang.reflect.Array; 提供了动态创建数组,以及访问数组的元素的静态方法
注意:java中无论生成某个类的多少对象, 这些对象都会对应于同一个Class对象。
3 方法介绍
方法关键字 |
含义 |
getDeclaredMethods() |
获取所有的方法 |
getReturnType() |
获得方法的放回类型 |
getParameterTypes() |
获得方法的传入参数类型 |
getDeclaredMethod("方法名",参数类型.class,……) |
获得特定的方法 |
|
|
构造方法关键字 |
含义 |
getDeclaredConstructors() |
获取所有的构造方法 |
getDeclaredConstructor(参数类型.class,……) |
获取特定的构造方法 |
|
|
父类和父接口 |
含义 |
getSuperclass() |
获取某类的父类 |
getInterfaces() |
获取某类实现的接口 |
4 获取Class的三种方式
Class.forName("java.lang.String");
2)、调用某个类的class属性来获取该类对应的class对象,如
Class.forName("java.lang.String");
3)、调用某个对象的getClass方法。
String s = "aa";
Class<?> clazz = s.getClass();
5 生成对象
a)、先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:
newInstance()方法可以返回一个实例,但是构造方法要是没有参数列表的,它相当于调用某个类的不带参数的构造方法,但是如果在初始化对象的时候要传参数,就要使用Constructor
Class<?> classType = String.class;
Object obj = classType.newInstance();
Class<?> classType = object.getClass();
Constructor cons = classType.getConstructor(new Class[]{});
Object obj = cons.newInstance(new Object[]{});
Class<?> classType = object.getClass();
Constructor cons = classType.getConstructor(new Class[]{String.class,int.class});
Object obj = cons.newInstance(new Object[]{"hello",3});
public class ReflectTester
{
//方法实现对Customer对象的拷贝操作
public Object copy(Object object) throws Exception
{
Class<?> classType = object.getClass();
/*Constructor cons = classType.getConstructor(new Class[]{});
Object obj = cons.newInstance(new Object[]{});
System.out.println(obj);
System.out.println("-----------");*/
//以上的两行代码等价于下面一行
//Object obj2 = classType.newInstance();
Constructor cons2 = classType.getConstructor(new Class[]{String.class, int.class});
Object obj2 = cons2.newInstance(new Object[]{"hello",3});
System.out.println(obj2);
return null;
}
public static void main(String[] args) throws Exception {
ReflectTester test = new ReflectTester();
test.copy(new Customer());
}
}
class Customer
{
private Long id;
private int age;
private String name;
public Customer()
{
}
public Customer(String name,int age)
{
this.name = name;
this.age= age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
6 反射生成多维数组
import java.lang.reflect.Array;
/**
*
* 用反射构造一个多维数组
*
*/
public class ArrayTester2 {
public static void main(String[] args) {
int[] dims = new int[]{5,10,15};
//newInstance()方法的第二个参数是代表生成数组的维度,所以生成的数组维度为5,10,15,长宽高
Object array = Array.newInstance(Integer.TYPE,dims);
//arrayObj是一个二维的数组
Object arrayObj = Array.get(array,3);
Class<?> classType = arrayObj.getClass().getComponentType();
//arrayObj是一个一维的数组
arrayObj = Array.get(arrayObj, 5);
Array.setInt(arrayObj, 10, 37);
int[][][] arrayCast = (int[][][])array;
System.out.println(arrayCast[3][5][10]);
}
}
反射访问私有(private)的方法
例子1、获取privete方法、
public class PrivateTest {
private String sayHello(String name)
{
return "hello" + name;
}
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestPrivate {
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
PrivateTest p = new PrivateTest();
Class<?> classType = p.getClass();
Method method = classType.getDeclaredMethod("sayHello", new Class[]{String.class});
method.setAccessible(true); //压制java的访问控制检查
String str = (String)method.invoke(p, new Object[]{"aaa"});
System.out.println(str);
}
}
public class Private2 {
private String name = "zhangsan";
public String getName()
{
return name;
}
}
/**
*
* 将Private2中的private属性name的值变为李四
*
*/
public class TestPrivate2{
public static void main(String[] args) throws Exception
{
Private2 p = new Private2();
Class<?> classType = p.getClass();
Field field = classType.getDeclaredField("name");
field.setAccessible(true);
field.set(p, "lisi");
System.out.println(p.getName());
}
}