开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
前言:
我们知道java是面向对象的语言,一切都是对象,我们在一般都会使用new关键字来创建对象,其实java还提供了一种创建对象的方式,那就是java的反射机制。
一、反射是什么?
官方文档中对反射的解释:反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法。
简单来说就是我们不用在编译期就确定对象的类型,将确定对象类型这一步放到程序运行期去了。现在不理解这句话没事,看完反射这一系列的文章后你会理解这句话的。
二、反射常用Api
Class
Clase对象里面是存的类的一些信息
- 怎样获取Class对象
User user = new User(); // 使用new关键字
Class.forName("user"); // Class.forName()
Class<? extends User> userByGetClass = user.getClass(); // 对象的getClass();
Class<User> userClass = User.class; // 类.class
- Class对象常用Api
- class.newInstance():调用缺省构造函数,返回该对象的一个实例
- class.getDeclaredFields():返回field对象的一个数组,所有访问修饰符的字段类型
- class.getFields():获取public修饰的属性字段
- class.getClassLoader():返回该类的类加载器
- class.getSuperclass():返回该类的父类
- class.getMethods():返回该对象的所有方法
Api较多,就不一一列出来,大家可以自行去了解下
Field
-
怎样获取Field对象(通过class对象获取)
- Class.getFields():获取public修饰的属性字段。
- getDeclaredFields():获取类中所有属性(public protect default private)不包括继承父类中的字段。
- getField(String name):获取类特定的方法,name 参数指定了属性的名称
- getDeclaredField(String name):获取类特定的方法,name 参数指定了属性的名称
-
Field 对象常用Api
- field.setAccessible(boolean flag):启用或禁用安全检查,true禁用,false启用
- field.getType():返回这个变量的类型
- filed.getName():返回这个属性的名称
- field.get(Object obj):返回指定对象obj上此字段的值
- field.set(Object obj, Object value):设置obj对象的当前字段值为value;
Method
-
怎样获取Method对象(通过class对象获取)
- class.getMethods():获取类中被public修饰的方法
- class.getMethod(String name, Class... paramTypes):根据名称和参数类型获取对应方法,只能获取被public修饰的方法,否则会报NoSuchMethodException错误
- class.getDeclaredMethods():获取所有方法(排除继承父类的方法).
- class.getDeclaredMethod(String name, Class... paramTypes):根据名字和参数类型获取对应方法.
-
Method 对象常用Api
- method.getName():获取方法名
- method.getReturnTypes():获取返回值的类型
- method.getParameterTypes():获取参数类型的数组
- method.invoke(Object obj,Object…args):为object对象执行此方法。如果为静态方法obj传null即可,非静态方法需要传对象实例
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method stringMethod = String.class.getMethod("valueOf", Object.class);
Integer num = 5;
Object invoke = stringMethod.invoke(null, num);
String typeName = invoke.getClass().getTypeName();
System.out.println(invoke); // 5
System.out.println(typeName); // java.lang.String
}
Constructor
-
怎样获取Constructor对象(通过class对象获取)
- class.getConstructor(Class..c);获得某个公共的构造方法
- class.getConstructors();获得所有的公共构造方法。
- class.getDeclaredConstructor(Class..c);获得某个构造方法。(任意访问修饰符的构造方法都能获取)
- class.getDeclaredConstructors();获得所有的构造方法。(任意访问修饰符的构造方法都能获取)
-
Constructor 对象常用Api
- constructor.getName();获得方法名
- constructor.newInstance(Object...args);使用当前的构造方法来创建一个对象;
Annotation
- 怎样获取Annotation对象(Class、Field、Method、Constructor都可以获取到)
- Annotation[] getAnnotations():获取该对象上的所有注解集合
- Annotation getAnnotation(Class annotaionClass):获取此对象上指定的注解
- Annotation[] getDeclaredAnnotations():获取该对象上的所有注解,会忽略继承的注解
- Annotation getDeclaredAnnotation(Class annotationClass):根据注解类型获得此对象上的注解,会忽略继承的注解
关于getAnnotations()和getDeclaredAnnotations()的差别可以看stackoverflow社区的回答stackoverflow.com/questions/1…
- Annotation 对象常用Api
- annotation.annotationType():获取注解的类型 返回值是一个class对象
总结
这篇文章主要是罗列出来一些常用的反射api,像上面的class、method、field中的api都是会经常用到的,本节还没有实际用到其中的api,下一章我会总结一下我在项目中用到反射的一些场景,还会带大家看一下一些开源框架中对于反射的用法,下一章是干货,大家一定不要错过哦。