2022.4.20 创建类的对象
有了Class对象,能做什么?
-
创建类的对象:调用Class对象的newlnstance()方法
-
1)类必须写一个无参数的构造器。
-
2)类的构造器的访问权限需要足够
-
1 package com.xing.reflection; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.InvocationTargetException; 5 6 public class Test08 { 7 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { 8 //获得Class对象 抛出异常ClassNotFoundException 9 Class c1 = Class.forName("com.xing.reflection.User"); 10 11 //构造一个对象 newInstance()默认返回Object类 需要强转 需要抛出异常InstantiationException, IllegalAccessException 12 User user =(User)c1.newInstance();//本质调用了类的无参构造器 User类必须写一个无参数的构造器,否则报错 13 System.out.println(user);//User{name='null', id=0, age=0} 14 15 } 16 }
思考?难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。
-
步骤如下:
-
1)通过Class类的getDeclaredConstructor(Class .. parameterTypes)取得本类的指定形参类型的构造器
-
2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
-
3)通过Constructor实例化对象
-
1 package com.xing.reflection; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.InvocationTargetException; 5 6 public class Test08 { 7 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { 8 //获得Class对象 抛出异常ClassNotFoundException 9 Class c1 = Class.forName("com.xing.reflection.User"); 10 11 //通过构造器创建对象 12 13 //1.获得构造器 抛出异常NoSuchMethodException 14 Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); 15 16 //2.通过构造器创建对象 默认返回Object类 需要强转 抛出异常InvocationTargetException 17 User user2 =(User)constructor.newInstance("小明", 001, 18); 18 System.out.println(user2);//User{name='小明', id=1, age=18} 19 20 } 21 }
-
调用指定的方法 通过反射,调用类中的方法,通过Method类完成。
-
通过Class类的getMethod(String name,Class...parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
-
之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。
-
-
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语言访问检查
-
1 package com.xing.reflection; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.Method; 7 8 public class Test08 { 9 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { 10 //获得Class对象 抛出异常ClassNotFoundException 11 Class c1 = Class.forName("com.xing.reflection.User"); 12 13 //通过反射调用普通方法 14 User user3 = (User)c1.newInstance( ); 15 //通过反射获取一个方法 16 Method setName = c1.getDeclaredMethod("setName", String.class); 17 //invoke(Object obj,Object...args) 对象名 方法值 18 setName.invoke(user3,"小明");//激活user3中的setName方法,并传入参数值:小明 19 System.out.println(user3.getName());//小明 20 21 22 //通过反射操作属性 23 User user4 = (User)c1.newInstance(); 24 //获取一个指定属性 抛出一个异常 oSuchFieldException 25 Field name = c1.getDeclaredField("name"); 26 27 name.setAccessible(true);//关闭权限检测 28 //set(Object obj,Object...args) 对象名 属性值 29 name.set(user4,"小红");//不能赋值 User类权限不够 不能设置私有变量 关闭权限检测就可设置 30 System.out.println(name.getName()); 31 32 33 } 34 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析