反射技术
Java反射是指在程序运行时获取已知名称的类或者已有对象相关信息的一种机制,包括类的方法,属性,父类等信息,还包括实例的创建和实例类型的判断等。可以动态获取到类中的各个方法等。
反射也是框架的灵魂,因此学习好反射对往后的框架学习很有帮助。可以多看看java API文档中反射各个方法的定义和使用
代码演示如下:
1.定义一个类
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
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 void eat(){
System.out.println("eat....");
}
}
2.进行演示反射技术:
public class demo_test {
/**
* 演示获取反射对象的三种方法
* Class.forName()
* 类名.Class
* 对象.getMethod
* 三种方式获取到的反射对象是同一个。
* @param args
*/
//反射 将类的各个组成成分封装为其他对象 可以动态获取到类中的各个方法
public static void main(String[] args) throws Exception {
//Class.forName()
Class cls1 = Class.forName("cn.itcast.domain.Person");//多应用于配置文件,读取文件加载类
System.out.println(cls1);
//类名.Class
Class cls2 = Person.class;//多用于参数的传递
System.out.println(cls2);
//对象.getMethod
Person p = new Person(); //用于获取对象的字节码文件
Class cls3 = p.getClass();
System.out.println(cls3);
// Constructor constructor = cls1.getConstructor(String.class,int.class);
// Object lisi = constructor.newInstance("lisi", 10);
// Method eat = cls1.getMethod("eat");
// eat.invoke(lisi);
}
}
2.1反射中方法演示:
/**
* 演示反射中获取对应的方法
* Field 成员变量
* Class 类
* Constructor 构造方法
* Method 类方法
*/
public class demo_test2 {
public static void main(String[] args) throws Exception {
//先获取到字节码文件
Class p = Person.class;
//此方法获取所有public修饰的成员变量
Field[] fields = p.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取指定public修饰的成员变量
Field a = p.getField("a");
//获取a的值
Person per = new Person();
Object o = a.get(per);
System.out.println(o);
System.out.println("================");
//获取所有的成员变量 不考虑修饰符
Field[] declaredFields = p.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
Field d = p.getDeclaredField("d");
//如何需要访问到公有以外的方法则需要忽略权限访问修饰符的安全监测 进行暴力反射
d.setAccessible(true);//暴力反射
Object o1 = d.get(per);
System.out.println(o1);
}
}
/**
* 反射中
* 统一解析构造方法 成员变量 成员方法的例子
*/
public class reflect_demo {
int m;
public reflect_demo(){}
public reflect_demo(int m){}
private void fun(){}
public void fun1(){}
public static void main(String[] args) throws ClassNotFoundException {
Class classInfo = Class.forName("cn.itcast.reflect.reflect_demo");
System.out.println("类A的构造函数如下:");
Constructor[] constructors = classInfo.getConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i].toString());
}
//获取类的所有变量
System.out.println();
System.out.println("类A的变量如下:");
Field[] declaredFields = classInfo.getDeclaredFields();
for (int i = 0; i <declaredFields.length ; i++) {
System.out.println(declaredFields[i].toString());
}
//获取类的所有方法
System.out.println();
System.out.println("类A的方法如下:");
Method[] declaredMethods = classInfo.getDeclaredMethods();
for (int i = 0; i <declaredMethods.length ; i++) {
System.out.println(declaredMethods[i].toString());
}
}
}
/**
* 反射中
* 统一的调用构造方法的例子
*/
public class reflect_demo1 {
public reflect_demo1(){
System.out.println("this is A");
}
public reflect_demo1(int m){
System.out.println("this is"+m);
}
public reflect_demo1(int m ,String n){
System.out.println(m+":"+n);
}
public static void main(String[] args) throws Exception, InstantiationException {
Class<?> reflect_demo1 = Class.forName("cn.itcast.reflect.reflect_demo1");
//调用空参数
Constructor<?> constructor = reflect_demo1.getConstructor();
System.out.println(constructor.newInstance());
//调用一个参数
/*如果传入的是数组 则调用方法如下
constructor = reflect_demo1.getConstructor(new Class[]{int.class});
Object o = constructor.newInstance(new Object[]{10});
*/
constructor = reflect_demo1.getConstructor(int.class);
//传入参数的方法
Object o = constructor.newInstance(10);
System.out.println(o);
//调用两个参数
/*如果传入的是数组 则调用方法如下
constructor = reflect_demo1.getConstructor(new Class[]{int.class,String.class});
System.out.println(constructor.newInstance(new Object[]{10,"hello"}));
*/
constructor = reflect_demo1.getConstructor(int.class,String.class);
Object hello = constructor.newInstance(10, "hello");
System.out.println(hello);
}
}
/**
*反射中
* 对于成员函数的使用
*/
public class reflect_demo2 {
public void fun(){
System.out.println("fun run..");
}
public void fun1(int m){
System.out.println("fun1 run.."+m);
}
public void fun2(int m,String n) {
System.out.println(m + "fun3 run" + n);
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> aClass = Class.forName("cn.itcast.reflect.reflect_demo2");
Object o = aClass.getConstructor().newInstance();
//调用无参数的成员函数
Method fun = aClass.getMethod("fun");
//执行方法
fun.invoke(o);
//调用一个参数的成员函数
Method fun1 = aClass.getMethod("fun1", int.class);
fun1.invoke(o,10);
//调用两个参数的成员函数
Method fun2 = aClass.getMethod("fun2", int.class, String.class);
fun2.invoke(o,10,"您好");
}
}
2.2反射中的一个小实例:
/**
* 对反射的练习
* 模拟一个"框架" 在不修改任何代码的情况下;可以创建任意对象,执行任意方法
*/
public class demo_test3 {
public static void main(String[] args) throws Exception {
//创建一个配置文件对象 并加载配置文件
Properties pro = new Properties();
InputStream resourceAsStream = demo_test3.class.getClassLoader().getResourceAsStream("pro.properties");
pro.load(resourceAsStream);
String className = pro.getProperty("className");
String classMethod = pro.getProperty("classMethod");
//利用反射技术创建对象并执行方法
Class aClass = Class.forName(className);
Object o = aClass.newInstance(); //创建对象
Method method = aClass.getMethod(classMethod);
method.invoke(o);
}
}