什么是Java的反射?
在运行状态中,对于任意一个类,都能够知道这个类的属性和方法;
反射的作用?
如果给定一个类名,就可以通过反射机制来获取类的所有信息,也可以动态的创建对象和编译;
反射的原理?
Java语言在编译之后会生成一个class文件,反射就是通过字节码文件找到其类中的方法和属性等;
反射的实现主要借助以下四个类:
1、Class:类的对象;
2、Constructor:类的构造方法
3、Field:类中的属性对象
4、Method:类中的方法对象
创建一个对象
Class class = Class.forname(XXX); Student student = (Student)class.newInstance();
获取类中的所有方法 Mehod
public static void main(String[] args) { try { Class<?> clz = Class.forName("fs.Student"); Method[] methods = clz.getMethods(); for (Method method : methods) { System.out.println("方法名:" + method.getName()); } } catch (ClassNotFoundException e) { e.printStackTrace(); } }
- Class.forName("fs.Student"):初始化指定的类
- clz.getMethods():获取类中所有的方法(包括其继承类的方法)
- class.getMethod(方法名,参数类型.class)
如果只需要获取加载类中的方法,不要父类的方法,可以使用下面的代码:
Method[] methods = clz.getDeclaredMethods();
Method是方法类,可以获取方法相关的信息,除了我们上面的方法名称,我们还可以获取其他的一些信息,比如:
- 方法返回类型:method.getReturnType().getName()
- 方法修饰符:Modifier.toString(method.getModifiers())
- 方法参数信息: method.getParameters()
- 方法上的注解: method.getAnnotations()
操作方法(invoke 对象名 参数)
try { Class<?> clz = Class.forName("fs.Student"); Student stu = (Student) clz.newInstance(); System.out.println(stu.getName()); Method method = clz.getMethod("setName", String.class); method.invoke(stu, "猿天地"); System.out.println(stu.getName()); } catch (Exception e) { e.printStackTrace(); }
获取类中的所有属性(Field)
Class<?> clz = Class.forName("fs.Student"); Field[] fields = clz.getFields(); for (Field field : fields) { System.out.println("属性名:" + field.getName()); }
clz.getFields()只能获取public的属性,包括父类的。
如果需要获取自己声明的各种字段,包括public,protected,private得用clz.getDeclaredFields()
Field是属性类,可以获取属性相关的信息,比如:
- 属性类型:field.getType().getName()
- 属性修饰符:Modifier.toString(field.getModifiers())
- 属性上的注解: field.getAnnotations()
操作属性
try { Class<?> clz = Class.forName("fs.Student"); Student stu = (Student) clz.newInstance(); Field field = clz.getDeclaredField("name"); field.setAccessible(true); System.out.println(field.get(stu)); field.set(stu, "猿天地"); System.out.println(field.get(stu)); } catch (Exception e) { e.printStackTrace(); }
field.setAccessible(boolean):;以取消Java的权限控制检查,让我们在用反射时可以访问访问私有变量
field.set(对象名,参数)
反射的优缺点?
优点
- 反射提高了程序的灵活性和扩展性,在底层框架中用的比较多,业务层面的开发过程中尽量少用。
缺点
- 性能不好
反射是一种解释操作,用于字段和方法接入时要远慢于直接代码,下面通过2段简单的代码来比较下执行的时间就可以体现出性能的问题