目录
一、什么是反射?
二、获取 Class对象 的三种方式
三、反射获取构造方法(Constructor)
四、反射获取成员变量(Field)
五、反射获取成员方法(Method)
一、什么是反射?
- 反射允许对成员变量,成员方法和构造方法的信息进行编程访问。
-
反射就是把java类中的各种成分映射成一个个的Java对象
-
例如:一个类有:成员变量、方法、构造方法等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
提问:为什么不能用IO流从上往下一行一行的进行读取呢?
- 但是当我们读取到构造方法和普通成员方法时,无法区分。
- 成员变量和局部变量也很难区分。
因此我们使用 反射 获取成员变量就可以得到成员所有信息
二、获取 Class对象 的三种方式
使用反射的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)
- Class.forName ( " 全类名 " ) ; (最为常用)
- 类名 . class (一般更多的是当做参数进行传递)
- 对象 . getClass ( ) ; (当已经有类对象是才能使用)
//第一种方式Class cl1 = Class.forName("反射.Student");System.out.println(cl1);//第二种方式Class cl2 = Student.class;System.out.println(cl2);System.out.println(cl1 == cl2);//第三种方法Student s = new Student();Class cl3 = s.getClass();System.out.println(cl3);System.out.println(cl1 == cl3);
三、反射获取构造方法(Constructor)
Class类中获取构造方法的方法:
Constructor <?> [ ] getConstructors() | 返回所有公共构造方法对象的数组 |
Constructor <?> [ ] getDeclaredConstructors() | 返回所有构造方法对象的数组 |
Constructor <T> getConstructor ( Class <> .. parameterTypes ) | 返回单个公共构造方法对象 |
Constructor <T> getDeclaredConstructor(Class <>.. parameterTypes) | 返回单个构造方法对象 |
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class cl1 = Class.forName("反射.Student");//利用反射获取构造方法Constructor[] con1 = cl1.getDeclaredConstructors();for (Constructor c : con1) {System.out.println(c);}Constructor con2 = cl1.getDeclaredConstructor(int.class);System.out.println(con2);//获取权限修饰符int modifiers = con2.getModifiers();//private :2 ,public:1 ,protected :4System.out.println(modifiers);//创建对象con2.setAccessible(true);//为了调用非public的方法,需要这样con2.newInstance(18);}
四、反射获取成员变量(Field)
Class类中获取成员变量的方法:
Field [ ] getFields() | 返回所有公共成员变量对象的数组 |
Field [ ] getDeclaredFields ( ) | 返回所有成员变量对象的数组 |
Field getField ( String name ) | 返回单个公共成员变量对象 |
Field getDeclaredField ( String name ) | 返回单个成员变量对象 |
Field类中用于创建对象的方法:
void set ( Object obj , Object value ) | 赋值 |
Object get ( Object obj ) | 获取值 |
// 1.获取Class字节码文件的对象Class clazz = Class.forName("ReFlect.Student");// 获取成员变量//获取所有的成员变量Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println(field);//private java.lang.String ReFlect.Student.name//private int ReFlect.Student.age//public java.lang.String ReFlect.Student.gender}//获取单个成员变量Field gender = clazz.getField("gender");System.out.println(gender);//public java.lang.String ReFlect.Student.gender//Field name = clazz.getField("name"); //无法获取 name是private私有的Field name = clazz.getDeclaredField("name"); System.out.println(name);//private java.lang.String ReFlect.Student.name//获取到成员变量后我们可以继续://1.获取权限修饰符int modifier = name.getModifiers();System.out.println(modifier); //2//2.获取成员变量名String n = name.getName();System.out.println(n); //name//3.获取数据类型Class<?> type = name.getType();System.out.println(type); //class java.lang.String//4.获取成员变量记录的值Student s = new Student("张三",23,"男");name.setAccessible(true);Object value = (String)name.get(s); //张三System.out.println(value);//5.修改成员变量记录的值name.set(s, "李四");System.out.println(s); //Student [name=李四, age=23, gender=男] }
五、反射获取成员方法(Method)
Class类中获取成员方法的方法:
Method [ ] getMethods ( ) | 返回所有公共成员方法对象的数组,包括继承的 |
Method [ ] getDeclaredMethods ( ) | 返回所有成员方法对象的数组,不包括继承的 |
Method getMethod ( String name , Cass <?> .. parameterTypes ) | 返回单个公共成员方法对象 |
Method getDeclaredMethod ( String name , Class<?>... parameterTypes ) | 返回单个成员方法对象 |
Method类中用于创建对象的方法:
Object invoke ( Object obj , Object... args ) | 运行方法 |
参数一:用obj对象调用该方法 参数二:调用方法的传递的参数(如果没有就不写) |
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {// 1.获取Class字节码文件的对象Class clazz = Class.forName("ReFlect.Student");// 2.获取里面所有的方法对象//(包含所有父类中的所有的公共方法)Method[] methods1 = clazz.getMethods();for(Method method : methods1) {System.out.println(method);}//获取里面所有的方法对象(只能获取本类中私有方法)Method[] methods2 = clazz.getDeclaredMethods();for(Method method : methods2) {System.out.println(method);}//3.获取指定单一方法对象Method m = clazz.getDeclaredMethod("eat", String.class);System.out.println(m); //private void ReFlect.Student.eat(java.lang.String)//1.获取权限修饰符int modifers = m.getModifiers();System.out.println(modifers); //2//2.获取方法名String name = m.getName();System.out.println(name); //eat//3.获取方法形参Parameter[] parameters = m.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter); //java.lang.String arg0}//4.获取方法返回值//5.获取方法抛出异常Class<?>[] exceptionTypes = m.getExceptionTypes();for(Class exceptiontype : exceptionTypes) {System.out.println(exceptiontype);//class Java.io.TOException//class java. lang. NullPointerException//class java. lang.ClassCastException}//方法运行Student s = new Student();m.setAccessible(true);m.invoke(s, "汉堡包");}