1、关于Class类
Class类 —— 现在有一个类,它的名字就是 Class。
在面向对象的世界里,万事万物皆对象。
Person p1 = new Person();
p1 是 Person类 的一个对象;
p1 的类型 是 Person类;
万事万物皆对象,类也是对象:
Person 是 Class类 的一个对象;
Person 的类型 是 Class类;
如何表示?
Class c1 = Person.class;
Class c2 = p1.getClass;
Class c3 = Class.forName("test.com.Person");
c1==c2==c3,这些对象均是 Person类 的 class type(类类型)
——一定程度上可以理解为 Person类 的字节码(非官方)
基本的类类型、void关键字都存在类类型
通过这个类类型,还可以创建 Person类 的对象:
// 无参数的构造函数
Person p = (Person)c1.newInstance();
2、Java 动态加载类
Class c = Class.forName("类型全称");
不仅表示了该类的类型,还代表了动态加载该类。
静态加载类:编译时刻加载的类;
——new 创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类;
动态加载类:运行时刻加载的类;
——c.newInstance()创建对象是动态加载,在运行时刻才进行加载;
3、通过 Class类 获取类的相关信息
String fullClassName = c.getName(); ——类型全称(含包名)
String simpleClassName = c.getSimpleName();——类型名称(不含包名)
/**
* Constructor类,构造方法对象
* 一个构造方法就是一个Constructor对象
* getConstructors()获取的是所有的public构造方法
* getDeclaredConstructors()获取的是该类自身定义的构造方法(无论是否是public都可以获取)
*/
Constructor[] cs = c.getConstructors();
String constructorName = ms[i].getName;——构造方法的名字
Class[] parameterTypes = ms[i].getParameterTypes();——参数列表类型的类类型数组
/**
* Method类,成员方法对象
* 一个成员方法就是一个Method对象
* getMethods()获取的是所有的public成员方法(含继承而来的)
* getDeclaredMethods()获取的是该类自身定义的成员方法(无论是否是public都可以获取,不含继承)
*/
Method[] ms = c.getMethods();
Method[] ms = c.getDeclaredMethods();
Class returnType = ms[i].getReturnType();——返回值类型的类类型
String methodName = ms[i].getName;——成员方法的名字
Class[] parameterTypes = ms[i].getParameterTypes();——参数列表类型的类类型数组
/**
* Field类,成员变量对象
* 一个成员变量就是一个Field对象
* getFieldss()获取的是所有的public成员变量(含继承而来的)
* getDeclaredFields()获取的是该类自身定义的成员变量(无论是否是public都可以获取,不含继承)
*/
Fields fs = c.getFields();
Fields fs = c.getDeclaredFields();
Class fileldType = fs[i].getType();——成员变量类型的类类型
String fileldName = fs[i].getName();——成员变量的名字
4、Java 方法反射的基本操作
如何获取某个方法
——同时确定方法的名称和方法的参数列表,才能唯一确定某个方法;
Method m = c.getMethod("print", new Class[]{int.class, int.class});
Method m = c.getMethod("print", int.class, int.class);
Method m = c.getMethod("print", new Class[]{});
Method m = c.getMethod("print");
方法反射的操作
——method.invoke(对象, 参数列表);
Object o = m.invoke(obj, Object[]{10, 20});
Object o = m.invoke(obj, 10, 20);
Object o = m.invoke(obj, Object[]{});
Object o = m.invoke(obj);
5、Java 通过反射了解集合泛型的本质
ArrayList list1 = new ArrayList();
ArrayList<String> list2 = new ArrayList<String>();
Class c1 = list1.getClass();
Class c2 = list2.getClass();
c1==c2 —— 编译之后集合的泛型是去泛型化的,反射的操作都是编译之后的操作
Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了
最后修改:2021-05-12 17:32:51
© 著作权归作者所有
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

发表评论