Class.forName(className)获取到Class
Class中存在方法getDeclaredConstructor获取它的构造函数
构造函数有newInstance方法获取实例
Class.forName("java.lang.String").getDeclaredConstructor(String.class).newInstance("zhong") |
Class类里不仅可以获得构造器,还可以获得属性和方法
其中Method很有意思,
原来调用方法是,"wang".equals("jian")。类在前,方法在后 |
现在可以用, Method equals = Class.forName("java.lang.String").getMethod("equals"); equals.invoke("wang","jian")的形式 |
注意method里会存参数类型等信息,使用不同类调用时要注意函数的参数是够相同 |
class位于java.lang.Class
其它的在java.lang.reflect里面Filed/Method/Constructor
Class实例对应着加载到内存中的一个运行时的类
在运行时,
判断一个对象所属的类
构造一个类的对象
判断类具有的成员变量和方法
获取泛型信息
调用对象的成员变量和方法
处理注解
生成动态代理
<
通过setAccessible(true);可以获取私有的属性和方法
javac.exe后会生成一个或多个字节码文件
java.exe对某个字节码文件解释运行,相当于把字节码文件加载到内存中
加载到内存中的类就成为运行时的类
此时运行中的类就作为Class的实例
加载到内存中的类会缓存一定时间,在此时间可以通过不同方式获取
类的加载(load)
类的连接(link)
类的初始化(init)
类加载器的作用
将class文件的字节码加载到内存中,并将静态数据转化为方法区运行时数据结构
带泛型不用强转了
方式一:运行时的类 的属性.class
Class
方式二:运行时类的对象 的方法getClass()
Class clazz2=p.getClass();
方式三:调用Class的静态方法:forName(String classPath)
Class clazz3=Class.forName("全类名");
方式四:使用类的加载器
ClassLoader classloader=RefectionTest.class.getClassLoader();
class clazz4=classloader.loadClass("全类名")
注意:clazz1==clazz2==clazz3==clazz4
外部内部各种类
接口
数组(数组的元素和类型一样,产生的Class对象就==)
枚举
注解
基本数据类型
甚至是void和Class本身
newInstance会创建一个运行类的对象
运行时类必须提供空参构造器
空参构造器的访问权限得够。通常设置public
(Person)clazz.newInstance(); //用泛型就不需要转了
这里是直接用clazz.new。之前的例子是先用getConstructor
可以看看视频:https://www.bilibili.com/video/BV1Kb411W75N?p=650
Field[] F=clazz.getFields();获取当前运行时类及父类所有public的属性
Field[] F=clazz.getDeclaredFileds();获取当前运行时类的所有属性(不包含父类,能获取私有)
f=F[0];获取一个属性
int m=f.getModifiers();获取权限修饰符,返回int 可以用Modifier.toString(m)翻译成文字
Class type=f.getType();type.getName();获取属性的类型
String name=f.getName();获取属性的名字
Method[] M=clazz.getMethods();获取当前运行时类及父类所有public的方法
Method[] M=clazz.getDeclaredMethods();获取当前运行时类的所有属性(不包含父类,能获取私有)
m=M[0];获取一个方法,权限修饰符/返回值类型/方法名/参数/throws/注解
Annotation[] annos=m.getAnnotations();
Modifier.toString(m.getModifiers());获取权限修饰符
m.getReturnType().getName();获取返回值
m.getName()获取方法名,可以和下面的形参组合使用
Class[] pars=m.getParameterTypes();拿到形参
Class[] es=m.getExceptionTypes();拿到异常
Constructor[] cons=clazz.getConstructors();获取当前运行时类中public的构造器
Constructor[] cons=calzz.getDeclaredConstructors();获取当前运行时类中所有的构造器
Type type=clazz.getSuperclass();获取父类
Type Ttype=clazz.getGenericSuperclass();获取带泛型的父类
获取父类的泛型
class[] interfaces=clazz.getInterfaces();
非静态要有运行时对象Person p=(Person)clazz.newInstance()
Field name=clazz.getField("name");
name.set(p,"wang")设置哪个对象的name,设置成什么
获取私有
Field name=clazz.getDeclaredField("name");
name.setAccessible(true);设置这个才能set
name.set(p,"wang")
Person p=(Person) clazz.newInstance();
Method show=clazz.getDeclaredMethod("show",String.class);指定方法,形参
show.setAccessible(true);
Object reV=show.invoke(p,"jian")方法的调用者,方法的形参值
invoke()方法的返回值即调用方法的返回值
调用静态方法
show.invoke(Person.class,"jian");其实写null也可以
Constructor cons=clazz.getDeclaredConstructor(String.class)
cons.setAccessible(true);
Person p=cons.newInstance("");