获取Class实例的方式与类加载器
1. java.lang.Class: 是反射的源头
2.如何获取Class的实例(3种)
3.关于类的加载器
TestReflection2
package com.aff.reflection; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.junit.Test; /* java.lang.Class: 是反射的源头 我们创建一个类,通过编译(javac.exe),生辰对应的.class文件。 之后我们使用java.exe加载(JVM的类的加载器)此class文件, .class文件加载到内存后,就是一个运行时类,存在缓存区中。 那么运行时类本身就是一个Class的实例 1.每一个运行时类只加载一次 2.有了Class实例以后,才能进行如下的操作 ①创建运行时类的对象 ②可以获取对应的运行时类的完整结构(属性,方法,构造器,内部类。。。) ③调用对应的运行时类的指定的结构(属性,方法,构造器) ④反射的动态代理 */ public class TestReflection2 { // 关于类的加载器 @Test public void test5() throws IOException, ClassNotFoundException { ClassLoader loader1 = ClassLoader.getSystemClassLoader(); System.out.println(loader1);// sun.misc.Launcher$AppClassLoader@7852e922 ClassLoader loader2 = loader1.getParent(); System.out.println(loader2);// sun.misc.Launcher$ExtClassLoader@330bedb4 ClassLoader loader3 = loader2.getParent(); System.out.println(loader3);// null // 自定义的类是由系统加载器加载的 Class clazz = Person.class; ClassLoader loader4 = clazz.getClassLoader(); System.out.println(loader4);// sun.misc.Launcher$AppClassLoader@7852e922 // String,Object又由上面的引导类加载的,所有加载不到的 String className = "java.lang.String"; Class clazz2 = Class.forName(className); ClassLoader loader5 = clazz2.getClassLoader(); System.out.println(loader5);// null // 掌握如下: //法一:指定目录下的jdbc.properties,可具体的包里 ClassLoader loader = this.getClass().getClassLoader(); InputStream is = loader.getResourceAsStream("com\\aff\\reflection\\jdbc.properties"); //法二:当前工程下jdbc.properties //FileInputStream is = new FileInputStream(new File("jdbc.properties")); Properties pros = new Properties(); pros.load(is); String name = pros.getProperty("user"); String password = pros.getProperty("password"); System.out.println(name + "\n" + password);//root \n 123abc } // 如何获取Class的实例(3种) @Test public void test4() throws ClassNotFoundException { // 1.调用运行时类本身的 .class Class clazz1 = Person.class; System.out.println(clazz1);// class com.aff.reflection.Person System.out.println(clazz1.getName());// class com.aff.reflection.Person Class clazz2 = String.class; System.out.println(clazz2.getName());// java.lang.String // 2.通过运行时类的对象获取 Person p = new Person(); Class clazz3 = p.getClass(); System.out.println(clazz3.getName());// com.aff.reflection.Person // 3.通过Class的静态方法获取,t通过此方式,体会,反射的动态性 String className = "com.aff.reflection.Person"; Class clazz4 = Class.forName(className); // clazz4.newInstance();//可以操作很多事 System.out.println(clazz4.getName());// com.aff.reflection.Person // 4.通过类的加载器(了解) ClassLoader classloader = this.getClass().getClassLoader();// 得到类加载器 Class clazz5 = classloader.loadClass(className);// System.out.println(clazz5);// class com.aff.reflection.Person } @Test public void test3() { Person p = new Person(); Class clazz = p.getClass(); System.out.println(clazz);// class com.aff.reflection.Person } }
3.关于类的加载器
类加载器是用来把类(class)装载进内存的。
JVM 规范定义了两种类型的类加载器:启动类加载器(bootstrap)和用户自定义加载器(user-defined class loader)。
JVM在运行时会产生3个类加载器组成的初始化加载器层次结构 ,如下图所示:
All that work will definitely pay off