java 的反射是一种运行时的自我识别技术,工作在运行时阶段,代码都在java.lang.reflect,主要对象是
Constructor:表示类中的构造方法
Field:表示类中的属性
Method:表示类中的方法
使用反射可以动态的创建对象、调用方法、获取该类的信息并进行动态处理、
从程序集中获取类型等。在我们开发过程中有着很大的应用,
反射的个人使用情况
对我个人而言,在开发共有的组件化的服务的时候总会使用反射解决动态化问题。本文简单的整理了下反射经常会用到的一些方法,后续再工作过程中应该会继续完善,也欢迎读者留言帮我完善反射知识,共同进步。
基本实验对象
package org.reflect.demo;
import java.io.Serializable;
import com.sun.istack.internal.NotNull;
public class Student extends Persion implements Serializable{
/**
*
*/
private static final long serialVersionUID = 169089621260109883L;
/**
* 学号
*/
@NotNull
private Long stuId;
public String className;
public Long getStuId() {
return stuId;
}
@Deprecated
public void setStuId(Long stuId) {
this.stuId = stuId;
}
protected void protectedMethod() {
}
@Override
public String toString() {
return "Student [stuId=" + stuId + ", className=" + className + "]";
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
package org.reflect.demo;
import java.io.Serializable;
public class Persion implements Serializable{
/**
*
*/
private static final long serialVersionUID = -8050349756611663247L;
private int age;
public String name;
protected int sex;
/**
* 私有方法測試
*/
private void name(){
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Persion [age=" + age + ", name=" + name + ", sex=" + sex + "]";
}
public Persion() {
super();
// TODO Auto-generated constructor stub
}
}
反射在类对象上的应用
/**
* 反射在类对象上的应用
*/
@Test
public void classInfo() throws Exception {
/**
* 通过反射获取到student的一个实例对象
*/
Class<?> stuClass = Class.forName("org.reflect.demo.Student");
Object stu = stuClass.newInstance();
assertThat(stu instanceof Student).isTrue();
Class<?> stuClass_2 = Class.forName("org.reflect.demo.Student", true, ClassLoader.getSystemClassLoader());
// Class<?> stuClass_2 = Class.forName("org.reflect.demo.Student", true, new ClassLoader() {
// });
Object stu_2 = stuClass_2.newInstance();
assertThat(stu_2 == stu).isFalse();
assertThat(stuClass_2 == stuClass).isTrue();
assertThat(stuClass_2.getClassLoader() == stuClass.getClassLoader()).isTrue();
assertThat(stu_2 instanceof Student).isTrue();
/**
* 获取父类
*/
System.out.println(stuClass.getGenericSuperclass());
/**
* 获取接口
*/
Type[] genericInterfaces = stuClass.getGenericInterfaces();
for (Type type : genericInterfaces) {
System.out.println(type.getTypeName());
}
}
反射在方法上的使用
/**
* 反射在方法上的使用
*/
@Test
public void methodInfo() throws Exception {
Class<Student> stuClass = Student.class;
System.out.println("********************************");
/**
* 获取本类的所有方法(包含父类)
*/
Method[] methods = stuClass.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
System.out.println("********************************");
/**
* 获取本类的所有非私有方法
*/
Method[] declaredMethods = stuClass.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method.getName());
}
System.out.println("********************************");
/**
* 获取指定方法名称的方法并赋值
*/
Method method = stuClass.getMethod("setStuId", Long.class);
System.out.println(method.getName());
Student stu = stuClass.newInstance();
method.invoke(stu, 10L);
System.out.println(stu.getStuId());
System.out.println("********************************");
/**
* 获取注解
*/
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.toString());
}
Deprecated annotation = method.getAnnotation(Deprecated.class);
System.out.println(annotation.toString());
/**
* 获取构造方法
*/
Constructor<?>[] constructors = stuClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.toGenericString());
}
}
反射在属性上的应用
/**
* 反射在属性上的应用
*/
@Test
public void fieldInfo() throws Exception {
Class<Student> stuClass = Student.class;
/**
* 获取所有的共有的属性包含父类的
*/
Field[] fields = stuClass.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
System.out.println("********************************");
/**
* declared 公开的 获取本类所有属性
*/
Field[] declaredFields = stuClass.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field.getName());
}
System.out.println("********************************");
Student stu = stuClass.newInstance();
/**
* 获取当前类的指定属性
*/
Field field = stuClass.getDeclaredField("stuId");
/**
* 开启暴力反射才可以执行属性赋值
*/
field.setAccessible(true);
field.set(stu, 10L);
System.out.println(stu.getStuId());
System.out.println("********************************");
}