扫描类的名称加载进来,用的反射
程序运行时变量是不可变的,现在动态加载类
JVM拿到的不是类的信息,而是类对象的信息,磁盘到JVM过度的阶段叫元空间,此时是类对象阶段。.class那个文件就是类对象阶段
不用的类放在内存中,运行的时候通过反射给动态加上去,这个变量是啥就是啥
可以实现不用知道这个变量是什么,后来用反射的方式动态加上去
这些东西在硬盘阶段,没有进到内存里边,怎么拿到对象,只知道Person类在reflect包下
都没有进到内存,只能通过反射把硬盘里的东西直接塞进内存,内存拿到类的所有信息就可以new出一个对象
所以不一定把类放进JVM中,放进本地内存、放进元空间就行
告诉类的位置(类的全名)
放工厂的信息,也可以当作一个对象,这个工厂也可以是一个对象,类本身也是一个对象
这个class1是个类对象,不是对象。这叫获取类对象
Field是字段的意思,每一个Field类型的东西形成一个数组。拿到是一个数组,下边遍历一下,可以指定获取,比如age属性包成一个对象
构造器主要作用是new对象,有了构造器内核的东西,可以通过构造器本身new出一个对象
这个就叫反射
这一串是全类名
在磁盘---Javac编译--->class文件(肉眼可以看见),再通过Java命令,把它加载到元空间,注意不是jvm,是过度的过程(系统的本地内存)
jvm是系统为java专门分配的内存,有限
class对象在本地内存(元空间)中放着,等着JVM调,内存存储块,生命周期短
用的时候直接调,相当于快速通道,调的时候从本地内存直接放到jvm
类对象就是new出对象之前一个混沌的状态
1.磁盘阶段-----》编译完还在磁盘放着2.把零散信息通过classloader(类加载器)加载到元空间(操作系统的本地内存),本地内存相对于jvm肯定更大一些,这个阶段可以通过反射搞定当Java需要的时候,把东西拖到3.jvm
1.classforName(”全类名“)最常用,啥也没有,不在内存中,用1
2.类名.class,随便一个类的class属性,在内存中基本成型了,用2
3.有对象了,拿类,用3
三个方法拿到的是一个东西
类加载过一次只要jvm不关闭,就不用再次加载
Object的getClass
类加载器classloader,在class类对象阶段,用反射Class.forName告诉类在哪
对象.getClass,类类型的一个对象(类对象)。只要JVM不关闭,就不用重新加载
工具通过反射的方式把方法列出来
解耦:把连在一起的东西分开操作
上面那一串东西可以放在属性文件,后缀是properties,以变量的方式赋值
有时候需要类类型的对象参数,类.class就是这个类对象
三个阶段获取类对象的方法
Java bean,属性都是封装的,然后用getName等
测试类。如何获取class对象的三种方法,地址都相等。拿到的都是元空间里的
第一种,告诉全名,就可以拿到类对象,在拿到构造器,才能new对象
第二种,已经找到Person了,直接Person.class
第三种,已经在jvm中了,可以直接new,对象.getClass()
三次获取的都是元空间的类对象,元空间就是操作系统的内存,不属于jvm,大于那个方法区,元空间不属于jvm,方法区是属于jvm的
jdk版本不同,元空间和方法区区分不一样
只有栈和堆有能力开辟空间,方法区只是一个放离散数据的地方,没有空间
class对象常用功能
拿方法调用,拿属性改变,拿构造器new对象
getFields()只能获取公开(不是私有的)的属性,得到是数组
加Declared的公开私有都能获取
Field是一个包下的类,String等基础类自动导入包
for each遍历
clz.getDeclaredFields()啥都能得到,也是数组
拿到了这两个属性,获取任意访问权限修饰符修饰的属性
要导包
for each循环
获取指定的属性
获取方法
遍历同上
打印出来很多方法
万一方法有重载,后面可以加参数来指定获取,但是参数要写成类对象的类型
要这样传,类.class
第二个参数是要找的方法的参数,要是类类型,获取基本数据类型同理,用包装类
把构造方法私有化,就是不能在外部new,要在类里new,单例模式,如任务管理器,只能打开一个窗口
获取构造方法
(method)是写错的
获取构造方法不用写名字,可以写参数
第一个参数都是调用者,因为调用方法需要开辟空间
获取Person类里的name属性
改变一个公有属性
修改类里的属性值,public的随便获取。age是私有的,会报错,禁止访问注意这个获取属性的方法,参数穿的是调用者,点之前是要改的属性
age是私有的,安全的,不能随便改变,只能提前设置,暴力反射,把安全检查忽略掉
加上这句话这样就可以改变私有的
拿到构造方法之后就可以new一个具体的对象了(newInstance),默认返回的是Object类型
多态
用子类方法需要强转
现在person是一个实例类,修改属性如下
有参数的实例类
通过反射的方式得到name属性,首先获取了getName方法,那么怎么调用他?
这样调
第一个参数是谁调用(实例对象调用),二三四。。个参数是方法的参数,无参就不写
这样只能得到方法的名字
后面要定义一个获取类名的方法,获取字段的方法,。。一个调用的方法,后面放到main里调用
获取类名
object是对象
属性文件里格式都是key=value
qcby.后面还有一个reflect,没截取上
无参构造方法的简单获取方法
读取配置文件
要想读取,就要放到内存中,类加载器可以放到内存中
把磁盘上的文件以流的方式读到内存
输入流
.load(方式)读取
读取的所有代码