一、引言
今天在通过反射访问私有方法时,程序一直抛NoSuchMethodException 异常。Method 存在却获取不到,那最有可能的情况就是因为参数类型不匹配而找不到。
原函数:
private void test(int value1, boolean value2, long value3)
反射获取方法报错代码:
Method methodtest = class1.getDeclaredMethod(“test”, Integer.class, Double.class,Long.class);
反射获取方法未报错代码:
Method methodtest = class1.getDeclaredMethod(“test”, int.class, double.class,long.class);
看到这,可能你会和我有一样的疑问:int不是基本数据类型吗?为什么还有Class对象啊?
二、正文
有9个预先定义好的Class对象代表8个基本类型和void,它们被java虚拟机创建,和基本类型有相同的名字boolean, byte, char, short, int, long, float, and double;这8个基本类型的Class对象可以通过java.lang.Boolean.TYPE,java.lang.Integer.TYPE等来访问,同样可以通过int.class,boolean.class等来访问。
拿int举例来说:
int.class与Integer.TYPE是等价的,但是与Integer.class是不相等的,int.class指的是int的Class对象,Integer.class是Integer的Class的类对象.。可以通过代码来验证:
public static void main(String[] args) {
Class<Integer> a = int.class;
Class<Integer> b = Integer.TYPE;
Class<Integer> c = Integer.class;
System.out.println(a == b);
System.out.println(a == c);
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(System.identityHashCode(c));
System.out.println(a+" ; "+c);
System.out.println(a.getName()+" ; "+c.getName());
}
输出结果:
true
false
1163157884
1163157884
1956725890
int ; class java.lang.Integer
int ; java.lang.Integer
补充:
这里System.identityHashCode 跟调用 hashcode是一样的效果,那这俩有什么区别?
1. 首先,System.identityHashCode(nullReference) 会返回0,但是 nullReference.hashCode() 会报错NullPointerException
2. 然后,如果我们重写了hashcode(),让结果return都是一样的hashcode,如果调用 System.identityHashCode,结果还是不一样的
3. System.identityHashCode()也能传入基本类型,会进行自动包装。
Integer.class 是Integer类型的类对象,类似的,int.class是是int类型的类对象。
作为一个特例,基本类型都有一个类对象,主要是用在反射中。
- Integer 是 Object Type 对象类型,int 是 Primitive Type 原始类型
- Integer 有成员变量,有成员方法,int 无成员变量,无成员方法
- Integer.class 与 int.class 不同;Integer.TYPE 与 int.class 相同
int和Integer之间是简单类型和包装类之间的关系。
但这两个的class对象则没有太多的关系,是Class类的两个不同实例而已。
三、结语
另外,反射这一块的内容还是挺多的,编写代码过程中难免会遭遇到各种各样的 Exception,推荐一篇不错的总结文章 反射进阶,编写反射代码值得注意的诸多细节