java 反射,类的加载过程以及Classloader类加载器
首先自定义一个类Person
package reflection; public class Person { private String name; public int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public Person() { super(); } public Person(String name) { super(); this.name = name; } public void show() { System.out.println("我是一个人"); } private String showNation(String nation){ System.out.println("我的国籍是"+nation); return nation; } }
然后是反射的一些操作
package reflection; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; import org.junit.jupiter.api.Test; public class ReflectionTest { @Test public void test1() throws Exception { Person p1 = new Person("Tom",12); //1.通过反射,创建Person类的对象 Class clazz = Person.class; Constructor cons = clazz.getDeclaredConstructor(String.class,int.class); Object obj = cons.newInstance("Tom",12); Person p = (Person)obj; System.out.println(p.toString()); //2.通过反射,调用对象指定的属性 Field age = clazz.getDeclaredField("age"); age.set(p, 10); System.out.println(p.toString()); //3.通过反射,调用方法 Method show = clazz.getDeclaredMethod("show"); show.invoke(p); System.out.println("**********************************************************"); } /* * 反射调用私有方法和属性 * */ @Test public void test2() throws Exception{ try { //通过反射调用私有的方法和属性 Class clazz = Person.class; //1.调用私有构造器 Constructor cons1 = clazz.getDeclaredConstructor(String.class); cons1.setAccessible(true); Person person = (Person)cons1.newInstance("zsben"); System.out.println(person); //2.调用私有属性 Field name = clazz.getDeclaredField("name"); name.setAccessible(true); name.set(person, "Lilei"); System.out.println(person); //3.调用私有方法 Method showNation = clazz.getDeclaredMethod("showNation",String.class); showNation.setAccessible(true); showNation.invoke(person, "中国"); //4.获得私有方法的返回值 String string = (String)showNation.invoke(person, "中国"); System.out.println(string); } catch (Exception e) { e.printStackTrace(); } } /* 关于Class类的理解 * 1.类的加载过程:使用java.exe命令对某个字节码文件进行解释运行, * 相当于将某个字节码文件加载到内存中,称为类的加载,加载到内存中的类,称其为运行时类 * 此运行时类就作为Class的一个实例 * 2.Class的实例对应着一个运行时类 * 3.加载到内存中的运行时类,会缓存一定的时间之内,我们可以通过不同的方式获取此运行时类 * * */ /* * 获取Class实例的四种方式 * */ @Test public void test3() throws ClassNotFoundException { //方式1:调用运行时类的属性;Class后面不加泛型也可以 Class<Person> clazz1 = Person.class; System.out.println(clazz1); //方法2:通过运行时类的对象 Person p1 = new Person(); Class clazz2 = p1.getClass(); System.out.println(clazz2); //方式3:调用Class静态方法forName(String classpath),classpath为类所在路径 Class clazz3 = Class.forName("reflection.Person"); System.out.println(clazz3); //方式4.使用类的加载器 ClassLoader classLoader = ReflectionTest.class.getClassLoader(); classLoader.loadClass("reflection.Person"); Class clazz4 = classLoader.loadClass("reflection.Person"); System.out.println(clazz1==clazz2); System.out.println(clazz1==clazz3); System.out.println(clazz1==clazz4); } }
类加载器的理解
package reflection; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import org.junit.jupiter.api.Test; /* * 类的加载过程: * 1.类的加载:将类的class文件读入内存,并为之创建Class对象,此过程由类加载器完成 * 2.类的链接:将类的二进制数据合并到JRE中,设置static变量的默认值(0,null,""等) * 3.类的初始化:JVM负责初始化,按顺序执行执行静态代码块和类属性的赋值 * * */ /* * 了解类的加载器 * * */ public class ClassLoaderTest { @Test public void test1() { //对于自定义类,得到ClassLoaderTest的类加载器:属于System Classloader,即系统类加载器 ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); System.out.println(classLoader); //调用系统类加载器的getParent().得到Extension Classloader,即扩展类加载器 ClassLoader classLoader2 = classLoader.getParent(); System.out.println(classLoader2); //Bootstap Classloader负责加载java核心类库,得不到了 ClassLoader classLoader3 = classLoader2.getParent(); System.out.println(classLoader3); //和3同理,String是java核心类库的 ClassLoader classLoader4 = String.class.getClassLoader(); System.out.println(classLoader4); } //读取读取配置文件 @Test public void test4() throws Exception { //方式1 Properties pros = new Properties(); FileInputStream fis = new FileInputStream("jdbc.properties"); pros.load(fis); String user = pros.getProperty("user"); String passwd = pros.getProperty("password"); System.out.println(user+passwd); } }
通过反射创建运行时类的对象
package reflection; import org.junit.jupiter.api.Test; /* * 通过反射创建对应的运行时类的对象 * */ public class NewInstanceTest { @Test public void test1() throws InstantiationException, IllegalAccessException {//实例化异常, 权限异常 Class<Person> clazz = Person.class; Object object = clazz.newInstance(); System.out.println(object); /* * newInstance()创建对应的运行时 类的对象 * 内部调用了空参数构造器 * */ Person person = clazz.newInstance();//这儿直接能得到person类运行时类对象 System.out.println(person); } @Test public void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException { String classPath = ""; classPath = "java.util.Date"; System.out.println(getInstance(classPath)); classPath = "reflection.Person"; System.out.println(getInstance(classPath)); } //此方法创建一个指定全类名的实例 public Object getInstance(String classPath) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class clazz = Class.forName(classPath); return clazz.newInstance(); } }