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

Java的反射机制与动态代理(一):反射

2017-03-28 00:00 716 查看
摘要: 1. 首先简单的介绍反射机制,会使用反射获取构造函数、类字段、方法等
2. 动态代理的使用情形及案例。

Java的反射属于高级特性内容,但是在开发中占据很重要的地位。通常我们使用类都是正向使用的,比如说创建Student类,我们想要调用类中的方法,就必须先要创建一个对象,然后用创建的对象去调用方法。而反射就是通过Class类去构造对象,不直接使用new运算符去创建对象。 如下的Student类,包含两个字段name和age,以及构造函数、私有的方法。

package com.dd171290.reflect;
public class Student {
public String name;
private int age;

private Student() {
name="default";
age=20;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
*此处省略了getter和setter方法以及hashCode、toString、equals方法
**/

private int myAge(){
return age;
}

}

如何通过Class来构建Student对象呢?

使用Class.forName方法返回一个Class对象,在Class对象中封装了很多操作构造函数、字段、方法、接口等方法,具体内容如下。

(1) 先获取Class类的对象

首先,你要确定构造类所在的包,本文中Student类位于包com.dd171290.reflect中,因此在调用

static String className="";
static Class<?> student;
static{
className="com.dd171290.reflect.Student";//构造类所在的包的路径
try {
student=Class.forName(className);//获取Class类的对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

(2) 如何获取Student类的实例

/**
* 获取对象的实例
* @throws IllegalAccessException
* @throws InstantiationException
*/
public void getNewInstance() throws InstantiationException, IllegalAccessException {
//调用newInstance方法获取类的实例
System.out.println(student.newInstance());
}

(3) 获取Student类的共有构造函数

public void getPublicConstructor() throws Exception{
System.out.println("-----获取类中公有的构造函数----");
//获取构造函数,String.class,int.class 对应构造函数的参数类型
Constructor<?> constructor=student.getConstructor(String.class,int.class);
Student s1=(Student)constructor.newInstance("val",23);
System.out.println(s1.getName());
System.out.println(s1.getAge());
}

(4) 获取Student类的私有构造函数

public void getPriConstructor() throws Exception{
System.out.println("-----获取类中私有的构造函数----");
//如果私有构造函数有参数,调用方法时,传递相对应的参数类型
Constructor<?> constructor=student.getDeclaredConstructor();
constructor.setAccessible(true);///强制取消Java的权限检测
Student s2=(Student) constructor.newInstance();
System.out.println(s2.getName());
System.out.println(s2.getAge());
}

(5) 获取Student类公有的成员变量

public void getPubFields() throws Exception{
System.out.println("-----获取类中公有的成员变量----");
//现获取类的构造函数
Constructor<?> constructor=student.getConstructor(String.class,int.class);
//实例化类的对象
Student s1=(Student)constructor.newInstance("val",23);
//获取名为name的字段
Field name=student.getField("name");
//使用set方法,为name字段设置值,其中s1是类对象
name.set(s1, "fv");
//使用get方法获取字段的值
System.out.println(name.get(s1));
}

(6) 获取Student类私有的成员变量

public void getPriFields() throws Exception{
System.out.println("-----获取类中私有的成员变量----");
Constructor<?> constructor=student.getConstructor(String.class,int.class);
Student s1=(Student)constructor.newInstance("val",23);
Field field=student.getDeclaredField("age");//获取私有字段age
field.setAccessible(true);// 强制获取访问权限
field.set(s1, 30);
System.out.println(field.get(s1));
}

(7) 获取Student类公有方法

public void getPubMethods() throws Exception{
System.out.println("-----获取到类中公有的方法----");
Constructor<?> constructor=student.getConstructor(String.class,int.class);
Student s1=(Student)constructor.newInstance("val",23);
Method method=student.getMethod("setAge",int.class);//第一个参数 方法名,第二参数,方法的参数类型
method.invoke(s1, 30);//s1是类的对象,30表示方法的实际参数
System.out.println(s1.getAge());

}

(8) 获取Studnet类的私有方法

public void getPriMethods() throws Exception{
System.out.println("-----获取类中私有的方法----");
Constructor<?> constructor=student.getConstructor(String.class,int.class);
Student s1=(Student)constructor.newInstance("val",23);
Method method=student.getDeclaredMethod("myAge");//第一个参数,方法名
method.setAccessible(true);//获取访问权限
Object object=method.invoke(s1);
System.out.println(object);
}

(9) 获取类Student的接口

//获取类的实现接口
Class<?> [] interfaces=student.getInterfaces();
//获取类的直接继承父类
java.lang.reflect.Type type=student.getGenericSuperclass();
System.out.println(type);

反射机制的用途:动态代理、Spring等都是通过反射来实现的。功能很强大。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: