java反射机制:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
测试类:
package io.renren.modules.base;
import lombok.Data;
@Data
public class ReflectionDemo {
public String name;
private String address;
private int age;
public ReflectionDemo(){
System.out.println("空参构造方法");
}
private ReflectionDemo(String name){
this.name = name;
}
public ReflectionDemo(String name,int age, String address){
this.name = name;
this.age = age;
this.address = address;
}
public ReflectionDemo(String name,int age){
this.age = age;
this.name = name;
}
//公有方法
public void eat(String food){
System.out.println("吃—"+food);
}
//私有方法
private void save(Double money,Integer age){
System.out.println("【"+this.name+"】存了【"+money+"】钱"+",今年:"+age+"岁");
}
}
开始测试:
package io.renren.modules.base;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
/**
* java类要经过编译—>运行两个阶段,编译器把.java文件编译成.class文件,
* 而运行时期,则需要把class文件读进内存,过程分为:加载到内存、连接解析、初始化
* 加载:把class文件读进内存,然后再创建一个class对象
* 连接:协调类的内部, 将类的二进制数据中的符号引用替换为直接引用
* 初始化
* 1. 创建类的实例
* 2. 类的静态变量,或者为静态变量赋值
* 3. 类的静态方法
* 4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
* 5. 初始化某个类的子类
*/
//@SpringBootTest
public class reflectionTest {
/**
* 获取类的加载器
*/
@Test
public void test1(){
Class c = ReflectionDemo.class;
System.out.println(c);
Class<? extends Class> aClass = c.getClass();
System.out.println(aClass);
ClassLoader classLoader = c.getClassLoader();
URL resource = classLoader.getResource("");
System.out.println(resource);
}
/**
* 获取类的class对象,字节码对象
*/
@Test
public void test2(){
//第一种方法
ReflectionDemo demo = new ReflectionDemo();
Class<? extends ReflectionDemo> aClass = demo.getClass();
System.out.println(aClass);
//第二种方法
Class c = ReflectionDemo.class;
System.out.println(c);
//第三种方法
try {
Class cn = Class.forName("io.renren.modules.base.ReflectionDemo");
System.out.println(cn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取构造方法、成员变量、成员方法
*/
@Test
public void test3() throws Exception{
//获取空参构造方法
Class c = ReflectionDemo.class;
//获取所有public构造方法
Constructor[] constructors = c.getConstructors();
for (Constructor con: constructors){
System.out.println(con);
}
//获取所有的构造方法,包括私有、公共
Constructor[] constructors1 = c.getDeclaredConstructors();
for (Constructor con: constructors1){
System.out.println(con);
}
//获取某个公共的构造方法,参数类型要对应
Constructor constructor = c.getConstructor(String.class, Integer.class);
ReflectionDemo object =(ReflectionDemo) constructor.newInstance("小明", 190);
System.out.println(object);
Constructor constructor1 = c.getConstructor();
System.out.println(constructor1);
//获取某个构造方法,包括私有、公有
Constructor declaredConstructors = c.getDeclaredConstructor(String.class);
Constructor declaredConstructors2 = c.getDeclaredConstructor(String.class, Integer.class);
System.out.println(declaredConstructors+"====="+declaredConstructors2);
//private,取消 Java 语言访问检查
declaredConstructors.setAccessible(true);
ReflectionDemo object2 =(ReflectionDemo) declaredConstructors.newInstance("小明");
System.out.println(object2);
//获取所有公有变量
Field[] fields = c.getFields();
for(Field f: fields){
System.out.println(f);
}
//获取所有变量
Field[] declaredFields = c.getDeclaredFields();
for(Field f: declaredFields){
System.out.println(f);
}
//获取公有变量
Field ageField = c.getField("name");
System.out.println(ageField);
//获取所有公有方法
Method[] method = c.getMethods();
for(Method m: method){
System.out.println(m);
}
//获取公有方法
Method method1 = c.getMethod("eat", String.class);
System.out.println(method1);
//获取方法、包括私有、公有
Method method2 = c.getDeclaredMethod("save", Double.class);
method2.setAccessible(true);
System.out.println(method2);
}
/**
* 获取成员变量
*/
@Test
public void test4() throws Exception{
Class c = ReflectionDemo.class;
//获取到有参构造方法
Constructor con = c.getDeclaredConstructor(String.class);
//赋值
con.setAccessible(true);
Object object = con.newInstance("小明");
System.out.println(object);
Field name = c.getField("name");
Object value1 = name.get(object);
Field name2 = c.getDeclaredField("age");
name2.setAccessible(true);
Object value2 = name2.get(object);
//没赋值,为null
Field name3 = c.getDeclaredField("address");
name3.setAccessible(true);
Object value3 = name3.get(object);
System.out.println(value1);
System.out.println(value2);
System.out.println(value3);
}
/**
* 执行方法
*/
@Test
public void test5() throws Exception{
Class c = Class.forName("io.renren.modules.base.ReflectionDemo");
Constructor constructor = c.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
Object object = constructor.newInstance("小明");
Method eatMethod = c.getMethod("eat", String.class);
eatMethod.invoke(object, "菜果");
Method saveMethod = c.getDeclaredMethod("save", Double.class,Integer.class);
saveMethod.setAccessible(true);
//反射执行方法,object,实例对象,也就是执行哪个实例的方法,方法的参数
saveMethod.invoke(object,200000d,24);
}
}