反射 reflect
Java通过反射来获得“动态性(程序运行期间改变程序结构)”,在执行期间,才动态获得类的内部信息、并直接操作内部属性和方法。
不需要事先(写代码/编译期)知道运行对象是谁。我的感觉是可以根据外部的输入,来动态获取不同对象的类的信息。
反射实例:
创建实体类Entity(pojo):
写完变量后:
1)创建构造函数:
右击,选择Generate(或者Alt+INS)
2) get & set 获取私有属性;toString方便调试
写main方法:
psvm然后Tab:
sout:
Class加载内存分析 https://www.bilibili.com/video/BV1p4411P7V3?p=9 (建议多看几遍)
字节码加载到内存=》链接合并到jvm环境,设置static默认初始值 =》类构造器clinit初始化
常量和static变量在链接时就已经赋值了,初始化之前就已经存在了,引用这些量不会导致初始化。
ClassLoader 类加载器
类加载器细分:
1. bootStrap - 根 类加载器(jre/ lib/ rt.jar)
2. ext - 扩展加载器 (jre/ lib/ ext/ ...)
3. app - 应用程序(系统类) 加载器,最常用
双亲委派机制
选择类加载器的顺序:
bootStrap->ext->app->custom。先找boot,再找ext、app,最后找costom也就是自己写的。都找不到就报错Class Not Found
好处:
防止用户乱定义类:比如自定义一个String类,这时会先从BootStrap找,所以不会轮到自定义的String类
Class c1 = user.getClass()
c1.getFields() getDeclaredFields() getField("Fieldname",String.class)按要求获取
c1.getMethods() getDeclaredMethods() getMethod("Methodname",String.class)
c1.getConstructors() getDeclearedConstructors()
1)由知道的c1这个Object,获取c1的Class的信息(属性)
2)由知道的c1这个Object,获取c1的Class的信息(方法)
3)由知道的c1这个Object,获取c1的Class的信息(构造器)
反射实例
本例反射方式中,将getName方法剥离出来,再使用invoke来调用user对象(getName也可用于调用其他对象)
最后看下耗时:
反射很慢,但有时候还是需要的
通过反射获取泛型 https://www.bilibili.com/video/BV1p4411P7V3?p=15
method.getGenericParameterTypes() method.getGenericReturnType()