Java Reflection
Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于ReflectionAPO取得任何类的内部信息,
并能直接操作任意对象的内部属性及方法
Java反射机制提供的功能
》在运行时判断任意一个对象所属的类
》在运行时构造任意一个类的对象
》在运行时判断任意一个类所具有的成员变量和方法
》在运行时调用任意一个对象的成员变量和方法
》生成动态代理
主要内容:
1.理解Class类并实例化Class类对象
2.运行时创建类对象并获取类的完整结构
3.通过反射调用类的指定方法、指定属性
4.动态代理
反射相关的主要API:
》java.lang.class:代表一个类
》java.lang.reflect.Method:代表类的方法
》java.lang.reflect.Field:代表类的成员变量
》java.lang.reflect.Construtor:代表类的构造方法
》。。。
/*
* java.lang.Class:是反射的源头
*
* Class类
*
* 我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的类加载器完成的)此.class文件,
* 此.class文件加载到内存以后,就是一个运行时类,存放在缓存区。那么这个运行时类本身就是一个Class的实例!
* 1.每个运行时类只加载一次!
* 2.有了Class的实例以后,我们才可以进行如下的操作:
* 1) 创建对应的运行时类的对象
* 2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在包、异常、注解、。。。)
* 3)调用对应的运行时类的指定结构(属性、方法、构造器)
* 4)反射的应用:动态代理
* 在Object类中定义了此方法被所有子类继承:
* public final Class getClass()
*
* 正常方式:引入需要的“包类”名称——>通过new实例化——>取得实例化对象
* 反射方式: 实例化对象——>getClass()方法——>得到完整的"包类"名称
*/
//运用反射机制创建对象,并且调用方法和属性
@Test
public void test1() throws Exception{
//1.创建反射调用运行时类的指定属性
Class clazz = Person.class;
Person p1 = (Person) clazz.newInstance();
//2.通过反射调用运行时类的指定的属性
Field f1 = clazz.getField("name");
f1.set(p1,"Yhs");
System.out.println(p1);
Field f2 = clazz.getDeclaredField("age");//对权限为私有的属性进行调用
f2.setAccessible(true);
f2.set(p1, 12);
System.out.println(p1);
//3.通过反射调用运行时类的指定的方法
Method m1 = clazz.getMethod("show");
m1.invoke(p1);//调用方法
Method m2 = clazz.getMethod("display", String.class);
m2.invoke(p1, "HongKong");
}
//如何获取Class的实例(3种)
@Test
public void test3() throws ClassNotFoundException{
//1.调用运行时类本身的.class属性
Class clazz1 = Person.class;
System.out.println(clazz1.getName());//reflect.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());//reflect.Person
//3.通过Class的静态方法获取
String className="reflect.Person";
Class clazz4 = Class.forName(className);
System.out.println(clazz4.getName());//reflect.Person
//4.(了解)通过类的加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz5 = classLoader.loadClass(className);
System.out.println(clazz5.getName());//reflect.Person
}
类加载器ClassLoader:
获取配置文件
//法一:配置文件在具体的包内
ClassLoader loader = this.getClass().getClassLoader();
InputStream is = loader.getResourceAsStream("配置文件路径");
//法二:在当前目录下
FileInputStream is = new FileInputStream(new File("当前工程下配置文件的文件名"));
Properties pros = new Properties();
pros.load(is);
String name = pros.getProperty("user");
System.out.println(name);
String password = pros.getProperty("password");
System.out.println(password);
@Test public void test5(){ //获取系统类加载器 ClassLoader loader1 = ClassLoader.getSystemClassLoader(); System.out.println(loader1);//sun.misc.Launcher$AppClassLoader@456d3d51 //扩展类加载器 ClassLoader loader2 = loader1.getParent(); System.out.println(loader2);//sun.misc.Launcher$ExtClassLoader@456d3d51
//都属于核心类库,无法被获取 ClassLoader loader3 = loader2.getParent(); System.out.println(loader3);//null
String className = "java.lang.String";
Class clazz1 = Class.forName(className);
ClassLoader loader4 = clazz1.getClassLoader();
System.out.println(loader5);
}
原文:https://www.cnblogs.com/yangHS/p/10701168.html