反射
Class类
获取文件字节码对象的三种方法
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException {
//获取文件字节码对象的三种方法
//Class类:描述文件对象的类
//1.通过对象获取
Person p=new Person();
Class c=p.getClass();
System.out.println(c);
//2.通过类名获取
Class c1=Person.class;
System.out.println(c1);
System.out.println(c==c1);//证明了字节码文件对象在堆里就一个
System.out.println(c.equals(c1));
//3.通过Class类中的静态方法forName(完整的包名+类名)获取
Class c2=Class.forName("com.oracle.demo02.Person");
System.out.println(c2);
}
}
![]()
通过反射获取构造方法并使用
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//Class类:描述文件对象
//Constructor类:描述构造方法的类
//Method类:描述方法的类
//Filed类:描述变量的类
public class Demo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Person的字节码文件对象
Class c=Class.forName("com.oracle.demo02.Person");//静态代码块
//获取该类中所有公共的构造方法 数组
Constructor[] cons=c.getConstructors();
for(Constructor con:cons){
System.out.println(con);
}
//获取该类中的公共空参构造
Constructor con1=c.getConstructor();
//使用构造方法对象去创建Person对象
Object obj=con1.newInstance();//这是个多态
System.out.println(obj);
Person p=(Person)obj;//强转调用自己独有的方法
p.eat();
//获取该类中的公共有参构造并使用
Constructor con2=c.getConstructor(String.class,int.class);
Object obj2=con2.newInstance("飒",1);
System.out.println(obj2);
//反射获取空参构造方法并运行的快速方式
//前提:1.被反射的类必须有空参构造方法
//2.该方法必须是public修饰
Object obj3=c.newInstance();//是Class类中的方法 不再是构造方法里的了
System.out.println(obj3);
}
}
![]()
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
method1();
//method2();
//method3();
}
public static void method1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class c=Class.forName("com.oracle.demo02.Person");
//反射获得Person类中所有的构造方法
/*Constructor[] cons=c.getDeclaredConstructors();
for(Constructor con:cons){
System.out.println(con);
}*/
//反射获得私有的有参构造
Constructor con=c.getDeclaredConstructor(String.class);
//暴力反射 破坏了程序的封装性,安全性 可以下面方法暴力反射 但不推荐
//调用父类的方法避免java语言的访问检查
con.setAccessible(true);
Object obj=con.newInstance("李四");
System.out.println(obj);
}
![]()
通过反射获取成员变量并使用
public static void method2() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{
//反射获取成员变量并改值
Class c=Person.class;
Field[] fileds=c.getDeclaredFields();
for(Field f:fileds){
System.out.println(f);
}
//获取Person类中的公共成员变量并改值
//快速创建一个Person对象
Object obj=c.newInstance();
Field field=c.getField("name");
field.set(obj, "张三");
System.out.println(obj);
}
![]()
通过反射获取成员方法并使用
public static void method3() throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
//反射成员方法,并调用
Class c=Person.class;
//快速创建一个Person对象
Object obj=c.newInstance();
//获取所有的方法
/*Method[] methods=c.getDeclaredMethods();
for(Method m:methods){
System.out.println(m);
}*/
//获取公共有参构造并调用
Method method=c.getMethod("sleep",String.class);
method.invoke(obj,"李四");
}
}
![]()
反射练习
泛型擦除
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
//泛型擦除 不推荐 了解
public class Demo04 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ArrayList<Integer> arr=new ArrayList<Integer>();
arr.add(1);
//获取字节码文件对象
Class c=arr.getClass();
Method method=c.getMethod("add",Object.class);
method.invoke(arr,"你好");
System.out.println(arr);//[1, 你好]
}
}
反射配置文件
public class Person {
public void eat(){
System.out.println("人");
}
}
public class Student {
public void study(){
System.out.println("学生学习");
}
}
public class Worker {
public void work(){
System.out.println("工人");
}
}
#ClassName=com.oracle.demo03.Person
#MethodName=eat
#修改这一部分就OK了
ClassName=com.oracle.demo03.Worker
MethodName=work
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Demo01 {
//1.准备配置文件,Properties 键值对方式存储
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//2.IO流去读取配置文件中的键值对 Reader
FileReader fr=new FileReader("config.properties");
//3.将文件中的键值对存储到集合中的Properties中
Properties pro=new Properties();
pro.load(fr);
fr.close();
//4.从集合中获取类名和方法名
String className=pro.getProperty("ClassName");
String methodName=pro.getProperty("MethodName");
//5.反射获取指定类的class文件对象
Class c=Class.forName(className);
//快速创建指定类对象
Object obj=c.newInstance();
//获取指定的方法
Method method=c.getMethod(methodName);
//6.运行指定的方法
method.invoke(obj);//工人
}
}