java---反射机制

package com.beicai.reflect;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

import org.junit.Test;

public class ReflectDemo {
//关于类的加载器:ClassLoader
@Test
public void test5() throws ClassNotFoundException, IOException{
ClassLoader loader1 = ClassLoader.getSystemClassLoader();
System.out.println(loader1);
ClassLoader loader2 = loader1.getParent();
System.out.println(loader2);
ClassLoader loader3 = loader2.getParent();
System.out.println(loader3);

Class clazz1 = Person.class;
ClassLoader loader4 = clazz1.getClassLoader();
System.out.println(loader4);

String className = "java.lang.String";
Class clazz2 = Class.forName(className);
ClassLoader loader5 = clazz2.getClassLoader();
System.out.println(loader5);

//掌握
//方法一:
ClassLoader loader = this.getClass().getClassLoader();
InputStream is = loader.getResourceAsStream("com//beicai//reflect//jdbc.properties");
//方法二:
//FileInputStream is = new FileInputStream(new File("jdbc.properties"));
Properties pros = new Properties();
pros.load(is);
String user = pros.getProperty("user");
System.out.println(user);
String pwd = pros.getProperty("password");
System.out.println(pwd);
}
//如何获取Class实例(3种)
@Test
public void test4() throws ClassNotFoundException{
//1.调用运行时类本身的.class属性
Class clazz1 = Person.class;
System.out.println(clazz1.getName());

Class clazz2 = String.class;
System.out.println(clazz2.getName());
//2.通过运行时类的对象
Person p = new Person();
Class clazz3 = p.getClass();
System.out.println(clazz3.getName());
//3.通过Class的静态方法获取
String className = "com.beicai.reflect.Person";
Class clazz4 = Class.forName(className);
System.out.println(clazz4.getName());
//4.(了解)通过类的加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz5 = classLoader.loadClass(className);
System.out.println(clazz5.getName());

System.out.println(clazz1 == clazz3);

}
/*
* java.lang.Class:是反射的一个源头
* 我们创建了一个类,通过编译(javac.exe)生成对应的.class文件
* 之后我们使用java.exe加载(JVM的类加载器完成的)此,.class文件
* 此.class文件加载到内存以后,就是一个运行时类,存放在缓冲区
* 那么这个运行时类本身就是一个Class的实例

* 1.每一个运行时类只加载一次
* 2.有了Class的实例以后,我们才可以进行如下的操作:
*  (1)创建对应的运行时类的对象
*  (2)获取对应的运行时类的完整结构
*   (属性,方法,构造器,内部类,父类,所在的包,异常,注解)
*  (3)调用对应的运行时类指定的结构(属性,方法,构造器)
*  (4)反射的作用:动态代理
*/

@Test
public void test3(){
Person p = new Person();
Class clazz = p.getClass();//通过运行时类的对象,调用getClass(),返回其运行时类
System.out.println(clazz);
}
//有了反射,可以通过反射创建一个类的对象,并调用其中的结构
@Test
public void test2() throws Exception {
Class<Person> clazz = Person.class;
//1.创建clazz对应的运行时类Person类的对象
//clazz.newInstance();
Person p = (Person)clazz.newInstance();
System.out.println(p);
//2.通过反射调用运行时类的指定的属性
//2.1 public的属性
Field f1 = clazz.getField("name");
f1.set(p, "薛之谦");
System.out.println(p);
//2.2 非public的属性
Field f2 = clazz.getDeclaredField("age");
f2.setAccessible(true);
f2.set(p,20);
System.out.println(p);
//3.通过反射调用运行时的指定的方法
Method m1 = clazz.getMethod("show");
m1.invoke(p);

Method m2 = clazz.getMethod("display",String.class);
m2.invoke(p,"中国");

}

@Test
public void test1() throws Exception{
Person p = new Person();
p.setAge(10);
p.setName("陈伟霆");
System.out.println(p);
p.show();
p.display("HK",10);
}
}

分享