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  }
复制代码

 


 
posted @   暴躁C语言  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示