一、什么是java中的反射
Java 反射,就是在运行状态中。
- 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等
- 获取任意对象的属性,并且能改变对象的属性
- 调用任意对象的方法
- 判断任意一个对象所属的类
- 实例化任意一个类的对象
- Java 的动态就体现在这。通过反射我们可以实现动态装配,降低代码的耦合度;动态代理等。反射的过度使用会严重消耗系统资源。
JDK 中 java.lang.Class 类,就是为了实现反射提供的核心类之一。
获取 Class 的方法 、一个 jvm 中一种 Class 只会被实例化一次
二、反射的一些常用方法
1.获取Class的实例(三种)
Class c = 类名.class; Class c = Class.forName("类的全限定类名"); Class c = 对象.getClass();
2.获取对象的类名
String className = c.getName();//获取全限定类名 String className = c.getSimpleName();//获取简单类名
3.获取Field(属性)
Field field = c.getField("属性名");//通过属性名获取public的属性 Field[] field1 = c.getFields();//获取所有的public修饰的属性 Field[] field2 = c.getDeclaredFields();//获取类所有的属性(包括各种访问修饰符修饰的属性)
3.1.Field的相关方法
String name = field.getName(); //获取属性名 Class<?> type = field.getType(); //获取属性的类型 Object value = field.get(obj); //获取obj对象的field属性的值 field.set(obj,Object value); //给obj对象的field属性赋值value
3.2.设置可访问性
//默认为false只能对public修饰的操作,设置true可对private修饰的操作 field.setAccessible(true); //可以用在被访问修饰符修饰的地方,
4.Class获取Constructor
方法 | 说明 |
getConstructor(Class<?> … parameterTypes) | 获取类中public修饰的,指定参数类型的构造方法 |
getConstructors() | 获取类中public修饰的所有构造方法 |
getDeclaredConstructor(Class<?>… parameterTypes) | 获取类中指定参数类型的构造方法,无关修饰 |
getDeclaredConstructors() | 获取类的所有构造方法,无关修饰 |
5.Class获取Method
方法 | 说明 |
getMethod(String name, Class<?>… parameterTypes) | 根据方法名,方法参数获取对应方法。范围:本类和所有继承类的public所修饰的方法 |
getMethods() | 获取所有的方法 。范围:本类和所有继承类的public所修饰的方法 |
getDeclaredMethod(String name, Class<?>… parameterTypes) | 根据方法名,方法参数获取对应方法。范围:本类所有的方法,无关修饰 |
getDeclaredMethods() | 获取本类中所有的方法 |
5.1.Method的相关方法
方法 | 说明 |
getName() | 获取方法名 |
isVarArgs() | 如果该方法声明为采用可变数量的参数,则返回true; 否则返回false |
getModifiers() | 获取权限修饰符 |
getReturnType() | 获取返回类型 |
getExceptionTypes() | 获取所有抛出的异常类型 |
getParameterTypes() | 获取所有参数的类型 |
getParameterCount() | 获取所有参数的个数 |
getAnnotations() | 获取修饰该方法的注解集合 |
getAnnotation(Class annotationClass) | 获取指定的注解信息 |
getDeclaringClass | 获取方法所在的类的.class对象 |
invoke(Object obj, Object… args) | 执行底层的方法(反射类的方法,注意访问权限,是否给予参数)Object o:类的实例,c.getDeclaredConstructor().newInstance(),注意原来的c.newInstance()从jdk1.9开始已过期 |
6.Class获取包名
Class<?> c = Class.forName("java.lang.String"); Package cpackage = c.getPackage(); System.out.println(cpackage.getName()); //获取包名 System.out.println(c.getPackageName());//获取包名
7.获取类加载器
Class c = Test.class; ClassLoader loader = c.getClassLoader(); //获取类加载器 System.out.println(loader.getName());//获取加载器的名称
8.获取注解
Class c = Test.class; Annotation[] annotations = c.getAnnotations();//返回 直接存在于此元素上的注解 Annotation[] annotations = c.getDeclaredAnnotations();//返回此元素上 存在的注解(有可能是继承的)