反射详解
1、反射概述
什么是反射?
1.反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力
2.在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。
3.简单的来说,反射机制指的是程序在运行时能获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制类获得类的所有信息。包括其访问修饰符、父类、实现的接口、属性和方法的所有信息,并可在运行时创建对象、修改属性(包括私有的)、调用方法(包括私有的)
2、反射机制
1.为什么要用反射机制?直接创建对象不完了吗,这就涉及到了动态和静态的概念
1.静态编译
在编译时确定类型,绑定对象,即通过。
Student std = new Student("张三",30);
2.动态编译
运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,用以降低类之间的耦合性
Class.forName("com.mysql.Driver.class").newInstance();
一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在j2ee开发中
它的缺点就是对性能有影响,使用反射基本上是一种解释操作,这类操作总是慢于直接执行的相同操作
2.java反射机制给我们提供了以下功能
1.在运行时判断任意一个对象所属的类
2.在运行时构建任意一个类的对象
3.在运行时判断任意一个类所具有的成员变量和方法
4.在运行时调用任意一个对象的方法(包括私有的)
3、Class对象
1、Class对象是Reflection故事起源。要想操作类中的属性和方法,都必须从获取class对象开始
1、类是程序的一部分,每个类都有一个class对象。换言之,每当编写并且编译一个新类,就会产生与之对应的一个class对象
2、Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。
2、获取class对象的方式有多种
String str = "abc"; Class c = str.getClass();
List list = new ArrayList(); Class listClass = list.getClass(); Class superClass = listClass.getSuperclass();
Class listClass = ArrayList.class;
Class c1 = Class.forName("java.lang.String");
//基本数据类型 Class longClass = Long.TYPE; Class intClass = Integer.TYPE;
4、反射api
1、java.lang.reflect
Class类与java.lang.reflect一起对反射概念进行支持
java.lang包下:Class<T>表示一个正在运行的java应用程序中的类和接口,是Reflect的起源
java.lang.reflect包下
Field 类的成员变量
Method 类的方法
Constructor 类的构造方法
Array Array 类提供了动态创建和访问 Java 数组的方法
2、通过反射实例化对象
无参构造函数
Class.newInstance(); Class.getConstructor(new Class[] {}).newInstance(new Object[] {})
有参构造函数
Class.getConstructor(Class<?>... parameterTypes).newInstance(Object ... initargs);
3、通过反射获取并调用方法
获取当前类以及超类的public Method
Method[] arrMethods = classType.getMethods()
获取当前类声明的所有Method
Method[] arrMethods = classType.getDeclaredMethods()
获取当前类以及超类的指定的public Method
Method[] arrMethods = classType.getMethods(String name, Class<?>... parameterTypes)
获取当前类声明的指定的Method
Method[] arrMethods = classType.getDeclaredMethods(String name, Class<?>... parameterTypes)
通过反射动态运行方法
Object obj = method.invoke(Object obj,Objcet ... args)
4、通过反射获取并调用属性
获取当前类以及超类的public Field
Field[] arrFields = classType.getFields();
获取当前类声明的public Field
Field[] arrFields = classType.getDeclaredFields();
获取当前类以及超类指定的public Field
Field field = classType.getField(String name);
获取当前类声明的指定的public Field
Field field = classType.getDeclaredField(String name);
通过反射动态设定Field的值
field.set(Object obj,Object value)
通过反射获取Field的值
Object obj = field.get(Object obj)