要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取java.lang.Class实例?
方式 | 备注 |
---|---|
Class.forName(“完整类名带包名”) | 静态方法 |
对象.getClass() | |
任何类型.class |
注:以上三种方式返回值都是Class类型。
如果你只是希望一个类的静态代码块执行,其它代码一律不执行,可以使用:
Class.forName("完整类名");
这个方法的执行会导致类加载,类加载时,静态代码块执行。
Book实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
/**
* 测试反射获取类的定义
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws NoSuchMethodException
*/
@Test
public void testReflect() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException {
//测试反射获取
Class> bookClass = Class.forName("com.jjh.pojo.Book");
StringBuilder sb = new StringBuilder();
sb.append(Modifier.toString(bookClass.getModifiers())+ " class " + bookClass.getSimpleName() + "{\n");
//获取属性
Field[] fields = bookClass.getDeclaredFields();
for (Field field : fields) {
sb.append("\t");
sb.append(Modifier.toString(field.getModifiers()));
if(field.getModifiers()!=0) sb.append(" ");
//获取属性的类型
sb.append(field.getType().getSimpleName());
sb.append(" ");
//获取属性的名称
sb.append(field.getName());
sb.append(";\n");
}
sb.append("}");
System.out.println(sb);
}
运行结果:
public class Book{ private Integer id; private String type; private String name; private String description; }
/**
* 通过反射给对象属性赋值
*/
@Test
public void setProperty() throws Exception{
Class> bookClass = Class.forName("com.jjh.pojo.Book");
Object book = bookClass.newInstance();
Field nameField = bookClass.getDeclaredField("name");
//设置暴力反射赋值
nameField.setAccessible(true);
nameField.set(book,"大话西游");
System.out.println(book);
}
运行结果:
Book(id=null, type=null, name=大话西游, description=null)
注意:
若类的属性使用了private修饰,则要使用setAccessible(true)方法暴力赋值
/**
* 测试通过反射获取方法
*/
@Test
public void testMethodsReflect() throws Exception{
Class> carClass = Class.forName("com.jjh.pojo.Car");
Method[] methods = carClass.getDeclaredMethods();
StringBuilder sb = new StringBuilder();
for (Method method : methods) {
//方法的权限修饰符
String modifier = Modifier.toString(method.getModifiers());
sb.append(modifier+" ");
//方法的返回值类型
String returnType = method.getReturnType().getSimpleName();
sb.append(returnType+" ");
//方法的名称
String name = method.getName();
sb.append(name+"(");
//参数列表
Class>[] parameterTypes = method.getParameterTypes();
for(int i=0;i
运行结果:
public String getName() public String toString() public void setName(String) public Integer getId() public void setLocalDateTime(LocalDateTime) public String buy(String) public void setId(Integer) public LocalDateTime getLocalDateTime()
要素1:对象 userService
要素2:login 方法名
要素3:实参列表
要素4:返回值
/**
* 测试反射调用方法
*/
@Test
public void testMethodInvoke() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class> carClazz = Class.forName("com.jjh.pojo.Car");
Object car = carClazz.newInstance();
Method buy = carClazz.getDeclaredMethod("buy", String.class);
Field idFiled = carClazz.getDeclaredField("id");
idFiled.setAccessible(true);
idFiled.set(car,1);
Field nameFiled = carClazz.getDeclaredField("name");
nameFiled.setAccessible(true);
nameFiled.set(car,"丰田");
Field localDateTimeFiled = carClazz.getDeclaredField("localDateTime");
localDateTimeFiled.setAccessible(true);
localDateTimeFiled.set(car,LocalDateTime.now() );
Object result = buy.invoke(car, "张三");
System.out.println(result);
}
运行结果:
用户:张三购买了id为:1的车,在2023-06-16T19:51:19.853653600
通过Constructor的newInstance()方法构建对象,可以传参数,也可以无参数
/**
* 通过反射构造方法创建对象
*/
@Test
public void testConstructor() throws Exception{
Class> carClazz = Class.forName("com.jjh.pojo.Car");
Constructor> constructor = carClazz.getDeclaredConstructor(Integer.class,String.class,LocalDateTime.class);
Object car = constructor.newInstance(1,"比亚迪",LocalDateTime.now());
System.out.println(car);
}
运行结果:
Car{id=1, name='比亚迪', localDateTime=2023-06-16T20:09:17.424101200}
两个方法【Class类中的】
public native Class super T> getSuperclass()
public Class>[] getInterfaces()
/**
* 获取一个类的父类和它实现的接口
*/
@Test
public void testGetSuperClassAndInterface() throws ClassNotFoundException {
Class> arryListClazz = Class.forName("java.util.ArrayList");
Class> superclass = arryListClazz.getSuperclass();
Class>[] interfaces = arryListClazz.getInterfaces();
System.out.println("ArrayList的父类是: "+superclass.getSimpleName());
System.out.println("ArrayList实现的接口有:");
for (Class> anInterface : interfaces) {
System.out.println(anInterface);
}
}
运行结果:
ArrayList的父类是: AbstractList ArrayList实现的接口有: interface java.util.List interface java.util.RandomAccess interface java.lang.Cloneable interface java.io.Serializable