Java反射机制及其获取InputStream的两种方式

时间:2023-02-04 20:35:43

图一:

Java反射机制及其获取InputStream的两种方式



java.lang.Class:是反射的源头。
     我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的类加载器完成的)
     此.class文件,此.class文件加载到内存以后,就是一个运行时类,存在在缓存区。那么这个运行时类本身就是一个Class的实例!
     1.每一个运行时类只加载一次!
     2.有了Class的实例以后,我们才可以进行如下的操作:
         1)*创建对应的运行时类的对象
         2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在的包、异常、注解、...)
         3)*调用对应的运行时类的指定的结构(属性、方法、构造器)
         4)反射的应用:动态代理


示例代码:

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

import org.junit.Test;

public class TestReflection {
	/*
	 * 有了反射,可以通过反射创建一个类的对象,并调用其中的结构
	 */
	@Test
	public void test1() throws Exception {
		Class clz = Person.class;
		
		//1.创建clz对应的运行时类Person类的对象
		Person p = (Person) clz.newInstance();
		System.out.println(p);
		
		//2.通过反射调用运行时类的指定属性
		Field f1 = clz.getField("name");
		f1.set(p, "小明");
		System.out.println(p);
		
		Field f2 = clz.getDeclaredField("age");//获取声明的属性
		f2.setAccessible(true);//可见性设置为可见
		f2.set(p, 23);
		System.out.println(p);
		
		//3.通过反射调用运行时类的指定的方法
		Method m1 = clz.getMethod("show");
		m1.invoke(p);
		
		Method m2 = clz.getMethod("display", String.class);
		m2.invoke(p, "CHN");
	}
	
	/*
	 * 获取Class实例的3种方式
	 */
	@Test
	public void testGetClass() throws ClassNotFoundException {
		//1.调用运行时类本身的.class属性
		Class clz1 = Person.class;
		System.out.println(clz1.getName());
		
		Class clz2 = String.class;
		System.out.println(clz2.getName());
		
		//2.通过运行时类的对象获取
		Person p = new Person();
		Class clz3= p.getClass();
		System.out.println(clz3.getName());
		
		//3.通过Class的静态方法获取(通过此方法,体会一下反射的动态性)
		String className = "com.iting.testJava.main.Person";
		Class clz4 = Class.forName(className);
		System.out.println(clz4.getName());
		
		//4.(了解)通过类的加载器
		ClassLoader classLoader = this.getClass().getClassLoader();
		Class clz5 = classLoader.loadClass(className);
		System.out.println(clz5.getName());
	}
	
	/*
	 * 关于类的加载器:ClassLoader
	 */
	@Test
	public void testClassLoader() throws Exception {
		ClassLoader loader1 = ClassLoader.getSystemClassLoader();
		//System ClassLoader可直接获取
		System.out.println(loader1);//sun.misc.Launcher$AppClassLoader@dad5dc
		
		ClassLoader loader2 = loader1.getParent();
		//Extension ClassLoader可直接获取
		System.out.println(loader2);//sun.misc.Launcher$ExtClassLoader@9c9116
		
		ClassLoader loader3 = loader2.getParent();
		//Bootstrap ClassLoader无法直接获取
		System.out.println(loader3);//null
		
		//自定义类存放在System ClassLoader
		Class clz1 = Person.class;
		ClassLoader loader4 = clz1.getClassLoader();
		System.out.println(loader4);//sun.misc.Launcher$AppClassLoader@dad5dc
		
		//核心类库由Bootstrap ClassLoader加载
		String className = "java.lang.String";
		Class clz2 = Class.forName(className);
		ClassLoader loader5 = clz2.getClassLoader();
		System.out.println(loader5);//null
		
		/*
		 * 需掌握如下:
		 */
		ClassLoader loader = this.getClass().getClassLoader();//获取自定类的加载器(System ClassLoader)
		System.out.println(loader);//sun.misc.Launcher$AppClassLoader@dad5dc
		//方法一:放在包下
		InputStream is = loader.getResourceAsStream("com\\iting\\testJava\\main\\jdbc.properties");
		//方法二:放在工程下
		//FileInputStream is = new FileInputStream("jdbc1.properties");
		Properties pro = new Properties();
		pro.load(is);
		String user = pro.getProperty("user");
		System.out.println(user);
		String password = pro.getProperty("password");
		System.out.println(password);
	}
}

class Person {
	public String name;
	private int age;
	
	public Person() {
		super();
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = 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;
	}
	
	public void show() {
		System.out.println("我是好人!");
	}
	
	public void display(String str) {
		System.out.println("我的国籍是" + str);
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}