总结一句话就是:在程序运行中根据业务需要由 jvm 动态获取 Class 对象来创建对象、执行方法等操作 。是动态和灵活的而不是事先代码写死
获取 Class
三种方法:类.class;对象.getClass();Class.forName("全限定类名")
Class 常用方法
| 方法名 | 作用 | 说明 |
|---|---|---|
| forName() | 获取 Class 对象 | |
| getName() | 取全限定的类名(包括包名),即类的完整名字 | 可以通过 Class.forName() 获取 Class |
| getSimpleName() | 获取类名,不包括包名 | |
| getCanonicalName() | 取全限定的类名(包括包名) | 大多数情况下和 getName() 一样,但内部类和数组时不一样 不能通过 Class.forName() 获取 Class |
| isInterface() | 判断 Class 的引用是否是接口 | true 是接口;false 不是 |
| getInterfaces() | 获取 Class 的引用实现的所有接口 | |
| getSupercalss() | 获取 Class 的引用的直接父类 | 可以一层一层往上获取,直到 Object |
| newInstance() | 使用 Class 的引用的无参构造创建对象 | 没有无参构造会报错 |
| getFields() | 获取 Class 的引用所有的 public 字段,包括继承来的 | 类似的还有 getMethods() |
| getField(String name) | 获取 Class 的引用指定 public 字段,包括继承来的 | |
| getDeclaredFields() | 获取 Class 的引用所有的字段(public,private,proteced),只是自己的,不包括继承来的 | 也有 getDeclaredMethods() |
Field 常用方法
| 方法 | 作用 | 说明 |
|---|---|---|
| boolean | isEnumConstant() | 字段是否是枚举类型 |
| void set(Object obj, Object val) | 给字段设置值 | 哪个字段调用方法就是给哪个字段设置值,第一个参数是对象,第二个参数是值 对于 final 修饰的字段不会报错,但是实际上不会发生改变 |
| Object get(Object obj) | 获取字段的值 | |
| String getName() | 获取字段名 | |
| Class<?> getType() | 获取字段的 Class | |
| void setAccessible(boolean flag) | 设置字段的可访问性(暴力反射) | 非 public 字段调用 get 和 set 会报错,设置了可访问性之后能正常操作 |
Method 常用方法
| 方法 | 作用 | 说明 | 举例 |
|---|---|---|---|
| Method getDeclaredMethod(String name, Class<?>... parameterTypes) | 获取指定方法 | 只是自己的方法,包括 public,private,proteced 不包括继承的 |
clazz.getMethod("draw",int.class,String.class)方法名为 draw,两个参数一个是int,一个是string |
| Method[] getDeclaredMethods() | 获取所有方法 | 只是自己的方法,包括 public,private,proteced 不包括继承的 |
|
| Method getMethod(String name, Class<?>... parameterTypes) | 获取指定方法 | 只能是 public,包括继承来的 | |
| Method[] getMethods() | 获取所有方法 | 只能是 public,包括继承来的 | |
| Object invoke(Object obj, Object... args) | 调用方法 | 第一个参数是对象,第二个可变参数是方法的参数 | method.invoke(circle,15,"圈圈")调用 circle 的方法,参数是 15 和 "圈圈" |
| Class<?> getReturnType() | 方法的返回类型 |