Java反射机制介绍与详解
本文主要是自己学习Java反射机制时所做的比较,参考了b站上黑马程序员讲解Java反射的视频,视频链接下方有给出。此外,本文中所用到的代码,可通过下方百度网盘链接全部下载。
链接: 视频地址.
链接:代码百度网盘链接
提取码:1234
什么是反射?
Java反射机制就是指程序在运行过程中,对于任意一个类,都能知道这个类的所有方法和属性。对于任意一个对象,都能调用其属性和方法。
获取Class对象的方式
1.Class.forName(“全类名”) :将字节码文件加载进内存,返回class对象。
- 多用于配置文件,将类名定义在配置文件中。获取文件,加载类
2.类名.class:通过类名的属性class获取
- 多用于参数的传递
3.对象.getClass():getClass() 方法在Object类中定义
- 多用于对象的获取字节码的方式
Person类:
package com.zyy.Reflection;
/**
* @author zyy
* @create 2021-11-25 9:46
*/
public class Person {
private String name;
private int age;
public String sex;
public Student student;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(){
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", student=" + student +
'}';
}
public void eat(){
System.out.println("eat.....");
}
public void eat(String food){
System.out.println("eat....."+food);
}
}
package com.zyy.Reflection;
/**
* @author zyy
* @create 2021-11-25 9:50
*/
public class reflectTest01 {
public static void main(String[] args) throws ClassNotFoundException {
//1.Class.forName("全类名")
Class c1=Class.forName("com.zyy.Reflection.Person");
System.out.println(c1);
//2.类名.class
Class c2=Person.class;
System.out.println(c2);
//3.对象.getClass()
Person person=new Person();
Class c3=person.getClass();
System.out.println(c3);
//比较三个对象
//结果发现都为true,
// 结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,无论通过哪一种方式获取Class对象。
System.out.println(c1==c2);
System.out.println(c2==c3);
//结果为false
//结论:每一个物理字节码文件对应的Class对象都不相同
Class c4=Student.class;
System.out.println(c3==c4);
}
}
Class对象功能
-
获取功能
1.获取成员变量们
Field[] getFields() :获取所有public修饰的成员变量
Field[] getField(String name): 获取指定名称的成员变量
Field[] getDeclaredFields() :获取所有的成员变量,不考虑修饰符
Field[] getDeclaredField(String name)
2.获取构造方法们
Constructor<?>[] getConstructors()
Constructor getConstructor(类<?>… parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor getDeclaredConstructor(类<?>… parameterTypes)
3.获取成员方法们
Method getMethod()
Method getMethod(String name, 类<?>… parameterTypes)
Method getDeclaredMethod()
Method getDeclaredMethod(String name, 类<?>… parameterTypes)
4.获取类名
String getName()
package com.zyy.Reflection;
import java.lang.reflect.Field;
/**
* @author zyy
* @create 2021-11-25 10:14
* ### Class对象功能
* 获取功能
1.获取成员变量们
Field[] getFields()
Field[] getField(String name)
Field[] getDeclaredFields()
Field[] getDeclaredField(String name)
*/
public class reflectTest02 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//获取Person的CLass对象
Class personClass =Person.class;
// Field[] getFields() :获取所有public修饰的成员变量
Field[] fields=personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
// Filed[] getFiled(String name): 获取指定名称的成员变量
System.out.println("-----------------");
Field sex=personClass.getField("sex");
//获取sex的值
Person person=new Person();
Object value=sex.get(person);
System.out.println(value);
//设置sex的值
sex.set(person,"male");
System.out.println(person);
}
}
package com.zyy.Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @author zyy
* @create 2021-11-25 10:31
* 2.获取构造方法们
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(类<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
*/
public class reflectTest03 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class personClass=Person.class;
// Constructor<T> getConstructor(类<?>... parameterTypes)
Constructor constructor= personClass.getConstructor(String.class,int.class);
System.out.println(constructor);
//创建对象
Object person =constructor.newInstance("张三",21);
System.out.println(person);
}
}
package com.zyy.Reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author zyy
* @create 2021-11-25 10:38
* 3.获取成员方法们
Method getMethod()
Method getMethod(String name, 类<?>... parameterTypes)
Method getDeclaredMethod()
Method getDeclaredMethod(String name, 类<?>... parameterTypes)
*/
public class reflectTest04 {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Class personClass =Person.class;
//获取指定名称的方法
Method eat_method=personClass.getMethod("eat");
Person person=new Person();
//执行方法
eat_method.invoke(person);
Method eat_method2=personClass.getMethod("eat",String.class);
//执行方法
eat_method2.invoke(person,"apple");
}
}
反射案例
需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
实现:
1.配置文件
2.反射
步骤:
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2.在程序中加载读取配置文件
3.使用反射技术加载类文件进内存
4.创建对象
5.执行方法
pro.properties文件
className=com.zyy.Reflection.Person
methodName=eat
package com.zyy.Reflection;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @author zyy
* @create 2021-11-25 13:18
*
* 写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
*/
public class reflectTest05 {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//1.加载配置文件
//1.1 创建properties对象
Properties pro=new Properties();
//1.2加载配置文件,转换为一个集合
//1.2.1 获取class目录下的配置文件
ClassLoader classLoader=reflectTest05.class.getClassLoader();
InputStream is=classLoader.getResourceAsStream("pro.properties");
pro.load(is);
//2.获取配置文件中定义的数据
String className=pro.getProperty("className");
String methodName=pro.getProperty("methodName");
//3.加载该类进内存
Class cls=Class.forName(className);
//4.创建对象
Object obj=cls.newInstance();
//5.获取方法对象
Method method=cls.getMethod(methodName);
//6.执行方法
method.invoke(obj);
}
}