反射的操作方法
目标:通过反射获得User类的Class对象,得到该类的所有信息,构造User类的对象,调用普通方法,操作属性。
*创建User类(方便演示)
package Reflect;
public class User {
public int id;
protected int age;
private String uname;
public User(){
}
public User(int id, int age, String uname) {
super();
this.id = id;
this.age = age;
this.uname = uname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}
(一) 获得该类的所有信息演示:
System.out.println("========================获得Class对象===================================");
Class class1=Class.forName("Reflect.User");
System.out.println("========================获得类的名字===================================");
System.out.println(class1.getName());//获得包名+类名
System.out.println(class1.getSimpleName());//获得类名
System.out.println("========================获得可访问属性===================================");
//获得public修饰的属性
Field[] field1=class1.getFields();
for(Field fs:field1){
System.out.println(fs);
}
System.out.println("==========");
//获得所有的属性
Field[] field2=class1.getDeclaredFields();
for(Field fs:field2){
System.out.println(fs);
}
System.out.println("==========");
//获得单独属性(name的属性)
Field field3=class1.getDeclaredField("name");
System.out.println(field3);
System.out.println("========================获得的类方法===================================");
//获取类的所有方法
Method[] methods=class1.getDeclaredMethods();
for(Method m:methods){
System.out.println(m);
}
//获取类的单独方法
Method m01=class1.getDeclaredMethod("getUname", null);//用于区分重载方法
System.out.println(m01);
Method m02=class1.getDeclaredMethod("setUname", String.class);//用于区分重载方法
System.out.println(m02);
(二)构造User类对象
1)无参构造
方法一:
Class c=Class.forName("Reflect.User");
User u1=(User) c.newInstance();
方法二
Class<User> c=(Class<User>)Class.forName("Reflect.User");
User u1=c.newInstance();
2)有参构造
Constructor<User> c=clazz.getDeclaredConstructor(int.class,int.class,String.class);//获得有参构造器方法
User u2=c.newInstance(1,18,"wang2");
System.out.println(u2.getUname());//wang2
(三)调用普通方法
//方法一
User u3=clazz.newInstance();
u3.setUname("wang3");
//方法二(建议使用)
User u3=clazz.newInstance();
Method method=clazz.getDeclaredMethod("setUname",String.class);//获得了setUname(string){}方法
method.invoke(u3, "wang33"); //invoke表示激活
System.out.println(u3.getUname());
两方法比较:方法二更常用,因为获得的方法可以是从其他(数据库、游览器、文件)调过来的变量,体现反射的动态性,灵活度更高。
(四)操作属性
1)获得普通属性(注:用此方法获得私有属性会报错)
User u4=clazz.newInstance();
Field f=clazz.getDeclaredField("id");//获得了id属性
f.set(u4, 4);
System.out.println(u4.getId()); //4
2)获得private…等属性
User u4=clazz.newInstance();
Field f=clazz.getDeclaredField("uname");//获得uname属性
f.setAccessible(true);//这个属性不需要做安全检查,可以直接访问
f.set(u4, "wang4");
System.out.println(u4.getUname()); //System.out.println(f1.get(u4));
说明:setAccessible-启用和禁用访问安全检查的开关,true为关闭,false(默认)为开启。
注意:setAccessible检查需要耗时间,影响效率,有时候可以关闭以此来提高反射效率。
(五)操作泛型、操作注解(未完待续)
还没有评论,来说两句吧...