反射-动态创建对象执行方法(有了Class对象,能做什么、通过反射来动态创建一个对象、setAccessible:安全检查开头,关闭后可以访问私有属性)
上一章小结
在实际的操作中,取得类的信息的操作代码,并不会经常开发。一定要熟悉java.lang.reflect包的作用,反射机制。
如何取得属性、方法、构造器的名称,修饰符等。
有了Class对象,能做什么? 创建类的对象:调用Class对象的newlnstance()方法 1)类必须有一个无参数的构造器。 2)类的构造器的访问权限需要足够 思考?难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。 步骤如下: 1)通过Class类的getDeclaredConstructor(Class ... parameterTypes)取得本类的指定形参类型的构造器 2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。3)通过Constructor实例化对象
调用指定的方法 通过反射,调用类中的方法,通过Method类完成。 通过Class类的getMethod(String name,Class...parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。 之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。 1.实例化Class Class.forName()--->Person 2.找到sayHello() getMethod("sayHello");--->+ sayHello() void 3.invoke() 调用方法----》+ sayHello() void Object invoke(Object obj, Object ... args) Object 对应原方法的返回值,若原方法无返回值,此时返回null若原方法若为静态方法,此时形参Object obj可为null 若原方法形参列表为空,则Object[] args为null 若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。
setAccessible:安全检查开头,关闭后可以访问私有属性
Method和Field、Constructor对象都有setAccessible()方法。setAccessible作用是启动和禁用访问安全检查的开关。
参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。
提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。使得原本无法访问的私有成员也可以访问
≥参数值为false则指示反射的对象应该实施Java语言访问检查
package 反射;//动态创建对象,通过反射 import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Text2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException { //获得class对象 Class c1=Class.forName("反射.User1"); //构造一个对象 try { //输出的值都为空,因为本质上我们调用的是无参构造器,所以我们创建类的对象必须要有一个无参构造器 User1 user =(User1)c1.newInstance();//他给的是Object类型,但是我们知道他是什么类型的,所以这里强转成了User System.out.println(user); } catch(Exception e) { System.out.println("InstantiationException"); } finally { } //通过构造器创建对象,没有空参构造器也可以用,因为我们是指定了构造器 Constructor constructor= c1.getDeclaredConstructor(String.class,int.class,int.class); //操作对象 User1 user1 =(User1)constructor.newInstance("开心",001,24); System.out.println(user1); //通过反射调用普通方法 User1 user3 =(User1)c1.newInstance(); //对象 //通过反射获取一个方法 Method setName= c1.getDeclaredMethod("setName",String.class);//对象 //invoke:激活的意思 //参数列表:(对象,"方法的值"):方法是那个对象的,那我们就只需要传那个对象即可 //操作方法 setName.invoke(user3,"小怪");//给user3对象的,setName方法传递一个String的值 System.out.println(user3.getName()); //通过反射操作属性 User1 user4 =(User1)c1.newInstance(); //对象 Field name=c1.getDeclaredField("name"); //操作name //不能直接操作私有属性,我们需要关闭程序的安全检测,通过方法/属性,把setAccessible(true),设置为true即为关闭 name.setAccessible(true);//关闭权限检查,这样我们就可以设置私有的属性了和方法了,无关闭这个检查检查的话,我们就没有权限去修改私有的方法和属性了 name.set(user4,"小开心");//给user4对象设置值 System.out.println(user4.getName()); } } //实体类:pojo,entity:来表示实体类 class User1{ private String name; private int id; private int age; public User1(){ } public User1(String name,int id,int age){ this.name=name; this.id=id; this.age=age; } public void setName(String name){ this.name=name; } public String getName(){ return name; } //------------------ public void setId(int id){ this.id=id; } public int getId(){ return id; } //-------------- public void setAge(int age){ this.age=age; } public int getAge(){ return age; } //输出方法 public String toString(){ return "User{"+"name="+name+"id="+id+"age="+age+"}"; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)