Class类
-- 类是对象,类是java.lang.Class类的实例对象。
设Foo foo1 = new Foo();
任何一个类都是Class的实例对象,这个实例对象有三种表示方式:
-
第一种表示方式,在知道类名时使用
Class c1 = Foo.class;
- 实际在告诉我们任何一个类都有一个隐含的静态成员变量class
-
第二种表示方式,已知该类的对象通过
getClass
方法Class c2 = foo1.getClass;
-
第三种表达方式,通过
Class.forName
方法,Class c3 = Class.forName("com.imooc.reflect.Foo");
com.imooc.reflect.Foo是类的全称。
注:
- c1 == c2 == c3,因为一个类的类类型只有一个。并且需要获取类的信息(类成员变量/方法/构造方法/包名/注解等),必须先获取类的类类型(Class)。
- 可以通过类的类类型创建该类的对象实例, 即通过c1 或 c2 或 c3 创建Foo的实例
Foo foo = (Foo)c1.newInstance();
-- 编译时刻加载类是静态加载类,运行时刻加载类是动态加载类。
new创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类,一个类或者一个方法不存在,整个程序就通过不了编译。解决该问题可以使用动态加载类。
//动态加载类,在运行时刻加载
Class c = Class.forName(args[0]);
//通过类类型,创建该类对象
OfficeAble oa = (officeAble)c.newInstance(); //officeAble为类的共同接口(统一标准,多态),里面有start方法
oa.start(); //运行时刻传入的哪个类,就调用哪个类的start()实现
-- 方法反射的操作
method.invoke(对象,参数列表)
- 示例
要获取如下print(int, int)
方法:
class A{
public void print(int a,int b){
System.out.println(a+b);
}
}
- 要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型
A a1 = new A();
Class c = a1.getClass();
- 获取方法名称(print)和参数列表(int,int)
getMethod
获取的是public的方法。getDelcaredMethod
自己声明的方法。
Method m = c.getMethod("print", new Class[]{int.class,int.class});
或
Method m = c.getMethod("print", int.class,int.class);
a1.print(10, 20);
方法的反射操作是用Method对象来进行方法调用,和a1.print
调用的效果完全相同
Object o = m.invoke(a1,new Object[]{10,20});
或
Object o = m.invoke(a1,10,20);
- 方法如果没有返回值返回null,有返回值返回具体的返回值。
注:反射的操作(Class的操作,Method的操作等)都是绕过编译的。 java集合的泛型是为了防止输入类型错误,但只在编译阶段有效。
参考