Java反射机制
重要:.java文件–>(jvm)编译成.class文件,反射是在.class文件里操作,一般好的框架的封装都用到了反射(例如:Spring mybatis)
首先建立一个实体类
public class Student {
int sid;
private String sname;
public int getSid() {
return sid;
}
public String getSname() {
return sname;
}
public Student(int sid) {
this.sid = sid;
}
public Student() {
}
private Student(String sname){
this.sname=sname;
}
public void print(){
System.out.println("恭喜您,调用成功!");
}
private String getString(String str){
return str;
}
public void getInfo(){
System.out.println("正在调用getInfo方法");
}
}
一、获取.class文件(3种)
①getClass()方法 先获取实体类对象,在调用此方法
Student student = new Student();
Class c1 = student.getClass();
②类名 .Class
Class c2 = Student.class;
③Class.forName()
Class c3 = Class.forName("com.offcn.entity.Student");
二、获取构造方法(getConstructors() or getDeclaredConstructors())
/*---------------获取非私有的构造方法----------------*/
Constructor[] c = Class.forName("com.offcn.entity.Student").getConstructors();
for (int i = 0 ;i<c.length;i++){
System.out.println(c[i]);
}
/*--------------获取所有的构造方法------------*/
Constructor[] dc = Class.forName("com.offcn.entity.Student").getDeclaredConstructors();
for (int i = 0 ;i<dc.length;i++){
System.out.println(dc[i]);
}
三、通过构造方法实例化对象
①如果当前构造方法是无参的,默认参数为null,也可不写
Constructor studentC1 = Class.forName("com.offcn.entity.Student").getConstructor(null);
Object o1 = studentC1.newInstance(null);
Student student1 = (Student) o1;
student1.print();
②如果构造方法是有参的,参数为此方法中 参数类型.class
Constructor studentC2 = Class.forName("com.offcn.entity.Student").getConstructor(int.class);
Object o2 = studentC2.newInstance(2);
Student student2 = (Student) o2;
student2.print();
③如果构造方法是私有的
Constructor stundetC3 = Class.forName("com.offcn.entity.Student").getDeclaredConstructor(String.class);
//通过暴力反射去除私有
stundetC3.setAccessible(true);
Object o3 =stundetC3.newInstance("3");
Student student3 = (Student) o3;
student3.print();
四、获取实体类中的属性(getFields() or getDeclaredFields()),并且赋值
/**
* 获取student类里面公有的属性
*/
Field[] f = Class.forName("com.offcn.entity.Student").getFields();
for (int i=0;i<f.length;i++){
System.out.println(f[i]);
}
/**
* 获取student类里面所有的属性
*/
Field[] df = Class.forName("com.offcn.entity.Student").getDeclaredFields();
for (int i=0;i<df.length;i++){
System.out.println(df[i]);
}
/**
* 给私有属性赋值
*/
Field sname = Class.forName("com.offcn.entity.Student").getDeclaredField("sname");
sname.setAccessible(true);
sname.set(o1,"www");
System.out.println(student1.getSname());
五、获取实体类中的方法(getMethods() or getDeclaredMethods())
/**
* 获取所有的公有的方法
*/
Method[] methods = Class.forName("com.offcn.entity.Student").getMethods();
for(int i = 0;i<methods.length;i++){
System.out.println(methods[i]);
}
/**
* 获取所有的方法
*/
Method[] dMethods = Class.forName("com.offcn.entity.Student").getDeclaredMethods();
for(int i = 0;i<dMethods.length;i++){
System.out.println(dMethods[i]);
}
/**
* 获取单个公有的方法,并调用其方法
*/
Method getInfo = Class.forName("com.offcn.entity.Student").getMethod("getInfo");
//调用这个方法
getInfo.invoke(o2);
/**
* 获取单个私有的方法,并调用其方法
*/
Method getString = Class.forName("com.offcn.entity.Student").getDeclaredMethod("getString",String.class);
getString.setAccessible(true);
Object aaa = getString.invoke(o2, "aaa");
System.out.println(aaa);
六、用反射来忽略泛型
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//获取其class文件
Class aClass = list.getClass();
Method add = aClass.getMethod("add",Object.class);
add.invoke(list,1);
for (Object obj:list) {
System.out.println(obj);
}