Java反射之 getMethod() 与invoke的使用,int.class vs integer.class

1、forName 方法

   forName是一个静态方法,其作用:通过调用来获取类名对应的Class对象,同时将Class对象加载进来。

  如果将类名保存在字符串(如xml)中,就可以在程序运行时,动态调用加载。

注意:只有调用的参数是类名或者方法时,才可用。

2、newInstance()方法

   作用:将对象实例化。返回类型为Object。与new的区别在于,new可以带参,而newInstance()不可以,一边初始化无参类。通常与forName()配合使用。

   例:

 

 
  1. String str = "java.util.Date";
  2. Class cl1= Class.forName(str);//加载java.util.Date类
  3. Object obj = cl1.newInstance();//实例化cl1
 

   
3、getMethod()方法

 

   getMethod方法与getField方法类似,getField方法根据表示域名的字符串,返回一个Field对象。而getMethod方法则根据方法名称和相关参数,来定位需要查找的Method对象并返回。

  getMethod与getDeclareMethods方法的区别在于,后者返回一个Method对象数组,需要自己在结果中查找所需Method对象。

  原型: Method getMethod(String name,Class...parameterTypes)

   参数解释:name: method的名称

                       parameterTypes:method的参数类型的列表(参数顺序需按声明method时的参数列表排列)

   返回:符合method名称和参数的method对象

   抛出错误:NoSuchMethodException   

                      原因:没有找到所要查询的Method对象  或  Method名称为“<init>”或“<clinit>”

                       NullPointerException

                       原因:所要查询的Method对象的名称为null

                        SecurityException

                        原因:调用的类或其父类没有调用权限

  例:

 

 
  1. Method m1 = Employee.class.getMethod("getName");
  2. Method m2 = Employee.class.getMethod("raiseSalary",double.class);
 

  上面例子分别获得了Employee类的getName方法和raiseSalary方法的 方法指针m1,m2。

 

 

4、invoke方法

  作用:调用包装在当前Method对象中的方法。

   原型:Object invoke(Object obj,Object...args)

   参数解释:obj:实例化后的对象

                       args:用于方法调用的参数

   返回:根据obj和args调用的方法的返回值

   抛出错误:IllegalAccessException

                      原因:Method对象强制Java语言执行控制 或 无权访问obj对象

                        IllegalArgumentException

                       原因:方法是实例化方法,而指定需要调用的对象并不是实例化后的类或接口

  例:

 

 
  1. Class l = Class.forName("test1.A");
  2. Object obj1 = l.newInstance();
  3. Object[] obj2 = new Object[1];
  4. obj2[0] = new String("hello world");
  5. Method m = l.getMethod("a1",new Class[] { String.class });
  6. Object obj3 = m.invoke(obj1, obj2);  

    来自 java.lang.Class.isPrimitive API

    有九个预定义的 Class 对象来表示八种基本类型和 void。它们由 Java 虚拟机创建,并且与它们所表示的基本类型具有相同的名称,即 boolean、byte、char、short、int、long、float 和 double。

    这些对象只能通过以下公共静态最终变量 java.lang.Boolean.TYPE 、 java.lang.Integer.TYPE 等访问

    对我来说,理解 int.class 和 Integer.class 的最简单方法是停止认为 Integer 是一个包装器(这意味着它是“特殊的”)。事实上,将 int 视为一种特殊情况更容易,也可能更合适。

    Integer 只是一个普通的 Java 类,与例如没有什么不同。细绳。它派生自 Object ,操作方式类似于 Object ,在运行时您可以创建 Integer 的实例,该实例采用类似对象的内存布局,例如开头有一个指向 Integer.class 的指针,这就是 java.lang 的多态运行时行为的原因。

    Integer 实际上还没有什么特别的。如果你想象一个Java没有boolean、int、long这些原语,而只有Integer、Boolean、Long等,类型系统实际上是非常一致的。

    从概念上讲,您可以将 int 视为稍后出于性能原因引入的特殊类。最初,它与 Integer 无关。
    在创建 Java 时,对于计算量大的程序来说,为普通数字维护类似对象的内存布局是非常昂贵的。而且大多数算术运算甚至根本不涉及多态动态调度。
    例如。对数字调用诸如 toString 之类的方法的情况要少得多。

    int 是特殊的,因为它是一个类,其“实例”布置在内存中,并剥离了公共对象结构 - 只有四个连续字节,没有额外的元数据。

    因此,您无法执行 123.getClass() ,因为 int 123 的运行时内存布局没有类指针。 int.class 确实存在,但它与 Integer.class 完全无关(还)。从某种意义上说, int 更类似于 Void ,因为 Void.class 确实存在,但你永远不能在 o.class == Void.class 中拥有 object o 。

    Java就可以解决了,int就是int,Integer就是Integer。
    但是人们意识到,虽然不太常见,但能够将 int 视为普通 Java 对象仍然非常有用,否则您将始终必须至少维护两组方法 - 一组接受普通对象,另一组接受普通对象采用原语 - 尽管性能不是您关心的问题。
    在这些场景中,int 实际上表现得像 Integer。 Java 允许通过自动装箱过程自动进行这种转换,从而有效地使 int 和 Integer 相关。

    但 int 仍然是 int,Integer 仍然是 Integer(例如 int.class != Integer.class )。但是 Integer.class 中引入了一个额外的字段来指示它与 int.class 相关,即 Integer.TYPE 。所以 Integer.TYPE == int.class 。对我来说 Integer.TYPE 只是捕捉 Integer 和 int 相关的概念。如何使用它,或者它是否有用,都取决于你。

    实际上,int 和 Integer 在重要的地方仍然是不同的类型。例如:

    void accept (int value);
    void accept (Integer value);

    仍然被认为是两个重载。因此,在使用反射时,您可以使用 int.class 和 Integer.class 来区分两者。

    当不使用反射或某种形式的元编程时,由于无法从对象导航到 int.class,因此在代码中使用 int.class 的情况相对较少。
    有时会让人感到困惑,因为自动装箱语法似乎建议您应该获取 int.class:

    int value = 1;
    Class c = ((Object)value).getClass();

    但这只是一种幻觉,因为当您执行 ((Object)value) 时,您实际上是在创建一个具有相同值的新 Integer 实例。

    我唯一需要显式使用 int.class 和 Integer.class 的时候是构建一个泛型 api <T> T getValue(String name, Class<T> type); ,其中我需要区分 api 是否允许返回 null:

    Class (Java Platform SE 8 ) (oracle.com)

     

     

     

     
     
posted @ 2024-06-28 14:27  CharyGao  阅读(86)  评论(0编辑  收藏  举报