Java反射机制
参考:
https://www.imooc.com/learn/199(慕课网视频教程)
*侵删*
1. Class类
Class类:类类,即类的类
public class ReflectDemo {
|
public class Foo {
|
2. Class类动态加载类
区分静态加载和动态加载
... Foo foo = Class.forName(“xxx.xxx.xxx”); ... |
xxx.xxx.xxx类要实现统一的标准或者继承类或者实现接口
3. 获取方法信息
获取方法信息(或者说成员函数的信息)
... Class c = obj.getClass(); System.out.println(c.getName()); Method[] ms = c.getMethods(); Method m = null; for(int i = 0; i < ms.length; i++){ m = ms[i]; Class returnType = m.getReturnType(); Class[] parmTypes = m.getParameterTypes(); System.out.println(returnType.getName()); System.out.println(m.getName()); foreach(Class parmType : parmTypes){ System.out.println(parmType.getName()); } } ... |
4. 获取成员变量和构造函数信息
成员变量 |
Field[] fs = c.getDeclaredFields(); foreach(Field field : fs){ Class fieldType = field.getType(); System.out.println(fieldType.getName()); // 打印成员变量类型 System.out.println(field.getName()); // 打印成员变量名称 } |
构造函数 |
Class c = obj.getClass(); //Constructor[] cs = c.getConstractors(); //获取所有公有的构造函数 Constructor[] cs = c.getDeclaredConstractors(); //获取所有申明的构造函数 foreach(Constructor constructor : cs){ System.out.println(constructor .getName()); Class[] parmTypes = constructor.getParameterTypes(); //获取构造函数参数 foreach(Class parmType : parmTypes){ System.out.println(parmType.getName()); } } |
5. Java方法反射的基本操作
public class MethodDemo1 { public static void main(String[] args) { //要获取print(int ,int )方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型 A a1 = new A(); Class c = a1.getClass(); /* * 2.获取方法 名称和参数列表来决定 * getMethod获取的是public的方法 * getDelcaredMethod自己声明的方法 */ try { //Method m = c.getMethod("print", new Class[]{int.class,int.class}); Method m = c.getMethod("print", int.class,int.class);
//方法的反射操作 //a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同 //方法如果没有返回值返回null,有返回值返回具体的返回值 //Object o = m.invoke(a1,new Object[]{10,20}); Object o = m.invoke(a1, 10,20); System.out.println("=================="); //获取方法print(String,String) Method m1 = c.getMethod("print",String.class,String.class); //用方法进行反射操作 //a1.print("hello", "WORLD"); o = m1.invoke(a1, "hello","WORLD"); System.out.println("==================="); // Method m2 = c.getMethod("print", new Class[]{}); Method m2 = c.getMethod("print"); // m2.invoke(a1, new Object[]{}); m2.invoke(a1); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
} } class A{ public void print(){ System.out.println("helloworld"); } public void print(int a,int b){ System.out.println(a+b); } public void print(String a,String b){ System.out.println(a.toUpperCase()+","+b.toLowerCase()); } } |
6. 集合的反射
通过反射了解集合的本质
package com.imooc.reflect;
import java.lang.reflect.Method; import java.util.ArrayList;
public class MethodDemo4 { public static void main(String[] args) { ArrayList list = new ArrayList();
ArrayList<String> list1 = new ArrayList<String>(); list1.add("hello"); //list1.add(20);错误的 Class c1 = list.getClass(); Class c2 = list1.getClass(); System.out.println(c1 == c2); // 结果为ture //反射的操作都是编译之后的操作
/* * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的 * Java中集合的泛型,是防止错误输入的,只在编译阶段有效, * 绕过编译就无效了 * 验证:我们可以通过方法的反射来操作,绕过编译 */ try { Method m = c2.getMethod("add", Object.class); m.invoke(list1, 20);//绕过编译操作就绕过了泛型 System.out.println(list1.size()); System.out.println(list1); /*for (String string : list1) { System.out.println(string); }*///现在不能这样遍历 } catch (Exception e) { e.printStackTrace(); } }
} |