粗略的使用
import com.po.User;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionStudyTest {
public static void main(String[] args) throws Exception {
/*
1.源代码阶段使用Class类的静态方法来获取,将字节码文件加入内存返回class对象
多用于配置文件,在配置文件中加入全限定类名来反射
*/
Class<?> userClass1 = Class.forName("com.po.User");
System.out.println(userClass1);
/*
2.类加载过后可以使用 类名.class来获取
多用于参数传递
*/
Class<?> userClass2 = User.class;
System.out.println(userClass2);
/*
3.运行时可以用对象的 。getClass来返回一个class
用于对象获取字节码文件
*/
User user = new User("张三", 15);
Class<?> userClass3 = user.getClass();
System.out.println(userClass3);
/*
一个类在jvm中只有一个class实例:
同一个字节码文件只会加载一次,3个class一样的
*/
System.out.println(userClass1 == userClass2);
System.out.println(userClass2 == userClass3);
/*
Class对象功能:
获取功能:
c1. 获取成员变量们
Field[] getFields() :获取所有public修饰的成员变量
Field getField(String name) 获取指定名称的 public修饰的成员变量
Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
Field getDeclaredField(String name)
*/
Field[] userField = userClass1.getFields();
for (Field field : userField) {
System.out.println(field);
}
Field a = userClass1.getField("a");
System.out.println(a);
/*
Field:成员变量
f1. 设置值
* void set(Object obj, Object value)
f2. 获取值
* get(Object obj)
f3. 忽略访问权限修饰符的安全检查
* setAccessible(true):暴力反射
*/
Object value = a.get(user);
System.out.println("value:" + value);
a.set(user, 22);
System.out.println("设置后:" + user);
Field userName = userClass1.getDeclaredField("name");
userName.setAccessible(true);//暴力反射
Object name = userName.get(user);
System.out.println("name:" + name);
/*
c2. 获取构造方法们
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(类<?>... parameterTypes)
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor:构造方法
创建对象:
T newInstance(Object... initargs)
如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
*/
//获取构造
Constructor<?> constructor = userClass1.getConstructor(String.class, int.class);
User user1 = (User) constructor.newInstance("李四", 20);
System.out.println("user1:" + user1);
//一般无参构造
Constructor<?> constructor1 = userClass1.getConstructor();
User user2 = (User) constructor1.newInstance();
System.out.println("user2:" + user2);
//快速使用无参构造
Object user3 = userClass1.newInstance();
System.out.println("user3:" + user3);
/*
c3. 获取成员方法们:
Method[] getMethods()返回所有public方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
Method getMethod(String name, 类<?>... parameterTypes)
Method[] getDeclaredMethods()包括所有定义方法,但不包括继承的方法。当然也包括它所实现接口的方法。
Method getDeclaredMethod(String name, 类<?>... parameterTypes)
执行方法:
Object invoke(Object obj, Object... args)
获取方法名称:
String getName:获取方法名
*/
Method[] userMetheds1 = userClass1.getMethods();
Method[] userMetheds2 = userClass1.getDeclaredMethods();
for (Method userMethed : userMetheds2) {
System.out.println(userMethed);
}
Method getName = userClass1.getDeclaredMethod("setName", String.class);
getName.invoke(user,"改名了");
System.out.println("user:"+user);
/*
c4. 获取全限定类名
String getName()
*/
System.out.println(userClass1.getName());
}
}
创建一个my.properties
className=com.po.User
methodName=show
测试类
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectionUseTest {
public static void main(String[] args) throws Exception {
/*
可以创建任意类的对象,可以执行任意方法
不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法
*/
//1.加载配置文件
//1.1创建Properties对象
Properties pro = new Properties();
//1.2加载配置文件,转换为一个集合
//1.2.1获取class目录下的配置文件
ClassLoader classLoader = ReflectionUseTest.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("my.properties");
pro.load(inputStream);
//2.获取配置文件中定义的数据
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
//3.加载该类进内存
Class<?> aClass = Class.forName(className);
//4.创建对象
Object obj = aClass.newInstance();
//5.获取方法对象
Method method = aClass.getMethod(methodName);
//6.执行方法
method.invoke(obj);
}
}
修改配置文件就可以使用任何类的任何方法