今日分享开始啦,请大家多多指教~

这篇文章给大家先简简单单地说下类的加载,以及具体实现,能够本人操作一下哦!

类的加载

在程序运行后,首次应用某个类,会把这个类的字节码文件读取到内存,并且会将这个类的所有信息存到一个Class对象中。

简略步骤:

1:jvm执行代码,例如读到 new Student()

2 : 读取Student的字节码文件

3:把字节码文件的内容(读取成字节码对象)存储到办法区(以前的说法),1.8当前叫做元空间(貌似)

4:最初类加载实现当前,在堆空间创立内存空间。

类的加载机会(上面六种)

  1. 创立类的实例。(new 一个类)
  2. 类的动态变量,或者为动态变量赋值。
  3. 类的静态方法。
  4. 应用反射形式来强制创立某个类或接口对应的java.lang.Class对象。
  5. 初始化某个类的子类。
  6. 间接应用java.exe命令来运行某个主类。(编译 javac 类名.java, 运行 java.类名)

明天的反射也属于类加载机会的一种

先上代码:

类加载机会代码演示

  1. 创立类的实例。 动态代码块随着类的加载而加载,并且只执行一次。

  1. 类的动态变量,或者为动态变量赋值。

  1. 类的静态方法。

4.反射通过 Class.forName("全类名") 进行反射

5.通过子类实例

运行后果

都证实了这个stu类被加载了。

类加载器(临时先理解理解)

上面说说类加载器,类加载器是负责将理论空间中的某个class文件读取到内存中并且生成Class的对象。

Java中有三品种加载器,它们别离用于加载不同品种的class:

Java中有三品种加载器,它们别离用于加载不同品种的class:

  • 启动类加载器(Bootstrap ClassLoader):用于加载零碎类库<JAVA_HOME>\bin目录下的class,例如:rt.jar。
  • 扩大类加载器(Extension ClassLoader):用于加载扩大类库<JAVA_HOME>\lib\ext目录下的class。
  • 应用程序类加载器(Application ClassLoader):用于加载咱们自定义类的加载器。

进去代码看看,咱们是如何取得类加载器的

再点进getClassLoader()办法看看jdk是怎么形容的

图中看到,一些实现可能应用null来示意疏导类加载器,可能在此类中的实现返回null.

举个例子。

好了,接下来该回到反射的主题

反射的概念

它一种机制,利用这个机制就能够在程序中对类进行解析,并且能够操作类中所有成员(变量,办法,构造方法)。

应用反射须要一个前提,获取须要反射的那个类的字节码对象。

Class对象的获取形式

通过类名.class取得

通过对象名.getClass()办法取得

通过Class类的静态方法取得: static Class forName(“类全名”)

Tips:每个类的Class对象都只有一个


Class类罕用的办法

String getSimpleName(); 获取类名字符串String getName(); 获取全类名字符串


创立类的对象

1.T newInstance(): 创立Class对象关联类的对象。

2.通过Constructor类来创建对象

首先要获取结构器类

Class类中与Constructor相干的办法

1.Constructor getConstructor(Class… parameterTypes)* 依据参数类型取得对应的Constructor对象。

getConstructor()的源码形容

上个应用的代码

Java        /**         * 先用getConstructor() 获取Constructor<T>类对象         * 再通过这个对象实例T。 没有参数的用法         * @throws Exception         */        @Test        public void getPublicConstructorWithoutParameter() throws Exception {            Class<Student> studentClass = Student.class;            //先获取无参结构类对象。            Constructor<Student> constructor=studentClass.getConstructor();            //再通过这个实例办法,实例这个类            Student student = constructor.newInstance();        }        /**         * 先用getConstructor() 获取Constructor<T>类对象         * 再通过这个对象实例T。 有参数的用法         * @throws Exception         */        @Test        public void getPublicConstructor() throws Exception {            Class<Student> studentClass = Student.class;            //获取有参结构类            Constructor<Student> constructor=studentClass.getConstructor(int.class);            //输出参数实例化Student类            Student student = constructor.newInstance(1);         }

如图所述,如果传入了没有相干参数重载的结构器,会报NoSuchMethodException异样

2.Constructor getDeclaredConstructor(Class… parameterTypes)

  • 依据参数类型取得对应的Constructor对象
  • 能够是public、protected、(默认)、private修饰符的构造方法。
  • 如果是被protected、(默认)、private修饰符润饰的结构器,须要确定自身是否拜访到,如果不能拜访到就要设置权限,用setAccessible(true)。

暴力获取结构器,能获取包含public protected default private

通过getDeclaredConstructor()暴力获取Student类中除了public其余修饰符的结构器,但这个结构类对象须要设置权限,setAccessible(true)

具体要不要设置,得看这个修饰符自身是否拜访到相干资源。


图上是个反例。

3.Constructor[] getConstructors()取得类中的所有构造方法对象,只能取得public的

上代码:

通过getConstructors()获取所有public润饰的结构器类对象。

@Testpublic void getAllPublicConstructor(){    Class<Student> studentClass = Student.class;    Constructor<Student>[] constructors = (Constructor<Student>[]) studentClass.getConstructors();    for (Constructor<Student> constructor : constructors) {        System.out.println(constructor);    }}

遍历打印的后果:

4.Constructor[] getDeclaredConstructors()取得类中的所有构造方法对象

能够是public、protected、(默认)、private修饰符的构造方法。

通过getDeclaredConstructors()获取所有p润饰的结构器类对象。

@Testpublic void getAllAccessConstructor(){    Class<Student> studentClass = Student.class;    Constructor<Student>[] constructors = (Constructor<Student>[]) studentClass.getDeclaredConstructors();    for (Constructor<Student> constructor : constructors) {        System.out.println(constructor);    }}

遍历打印的后果:

获取成员办法

接下来的局部就不放代码演示了,就提供下api。

1 Method getMethod(String name,Class...args);

办法名和参数类型取得对应的成员办法对象,只能取得public的

2 Method getDeclaredMethod(String name,Class...args);

依据办法名和参数类型取得对应的成员办法对象,包含public、protected、(默认)、private的

3 Method[] getMethods();

取得类中的所有成员办法对象,返回数组,只能取得public润饰的且蕴含父类的

4Method[] getDeclaredMethods();

取得类中的所有成员办法对象,返回数组,只取得本类的,包含public、protected、(默认)、private的

通过反射拜访成员变量

Method对象罕用办法

  • Object invoke(Object obj, Object... args)
  • 调用指定对象obj的该办法
  • args:调用办法时传递的参数
  • void setAccessible(true)

设置"暴力拜访"——是否勾销权限查看,true勾销权限查看,false示意不勾销

通过反射获取类的成员变量

Class类中与Field相干的办法

  • Field getField(String name);
  • 依据成员变量名取得对应Field对象,只能取得public润饰
  • Field getDeclaredField(String name);
  • 依据成员变量名取得对应Field对象,包含public、protected、(默认)、private的
  • Field[] getFields();
  • 取得所有的成员变量对应的Field对象,只能取得public的
  • Field[] getDeclaredFields();
  • 取得所有的成员变量对应的Field对象,包含public、protected、(默认)、private的

通过反射拜访成员变量

Field对象罕用办法

**void  set(Object obj, Object value)**  **void setInt(Object obj, int i)**      **void setLong(Object obj, long l)** **void setBoolean(Object obj, boolean z)**  **void setDouble(Object obj, double d)**  **Object get(Object obj)   int    getInt(Object obj)**  **long getLong(Object obj)**  **boolean getBoolean(Object ob)** **double getDouble(Object obj)**  **void setAccessible(true);暴力反射,设置为能够间接拜访公有类型的属性。** **Class getType(); 获取属性的类型,返回Class对象。**

今日份分享已完结,请大家多多包涵和指导!