反射的操作方法
发布日期:2021-07-26 18:44:04 浏览次数:0 分类:技术文章

目标:通过反射获得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检查需要耗时间,影响效率,有时候可以关闭以此来提高反射效率。

(五)操作泛型、操作注解(未完待续)

上一篇:JAVA基础:Super()详解
下一篇:反射中类的加载与Class对象的联系