1. 反射
- 反射:将类的各个组成部分封装为其他对象,这就是反射机制。
- 成员变量:Field[] fields
- 构造方法:Constructor[] cons
- 成员方法:Method[] methods
2. 为什么用反射?
- 1.可以在程序运行过程中操作这些对象。例如idea提示
- 2.可以解耦,提高成宿可扩展性。
3. 获取class对象的方式
- 1.Class.forName(“全类名”) 将字节码文件加载进内存获取。
-
- 多用于配置文件,将类名定义在配置文件中,读取配置文件,加载类
- 2.类.Class 通过类名的属性class获取类对象。
-
- 3.对象.getClass:getClass()方法在Object类中定义。
-
4. 实现验证
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReflexTest {
@Test
public void reflex() throws ClassNotFoundException {
System.out.println( "------------获取类对象3中方式------------" );
Class<?> clazz = Class.forName( "com.zrj.junit.Person" );
System.out.println( clazz );
Class<Person> personClass = Person.class;
System.out.println( personClass );
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
System.out.println( aClass );
System.out.println( clazz == personClass );
System.out.println( clazz == aClass );
}
@Test
public void reflexFieldTest() throws Exception {
System.out.println( "------------获取成员变量------------" );
Class<Person> personClass = Person.class;
System.out.println( "获取类对象:" + personClass );
Field[] fields = personClass.getFields();
System.out.println( "获取public修饰成员变量:" + fields );
Arrays.stream( fields ).forEach( System.out::println );
System.out.println( "----------------------------------" );
Field a = personClass.getField( "a" );
System.out.println( "获取指定的 public修饰 成员变量" + a );
Person person = new Person();
Object obj = a.get( person );
System.out.println( "设置值前,获取a属性值:" + obj );
a.set( person, "张三" );
System.out.println( "设置值后,获取a属性值:" + a.get( person ) );
System.out.println( "----------------------------------" );
Field[] declaredFields = personClass.getDeclaredFields();
System.out.println( "获取所以成员变量不考虑修饰符:" + declaredFields );
Arrays.stream( declaredFields ).forEach( System.out::println );
Field ds = personClass.getDeclaredField( "d" );
ds.setAccessible( true );
Object obj2 = ds.get( person );
System.out.println( "获取私有变量:" + obj2 );
}
@Test
public void reflexConstructorTest() throws Exception {
System.out.println( "------------获取构造方法------------" );
Class<Person> personClass = Person.class;
System.out.println( "获取类对象:" + personClass );
Constructor<Person> constructor = personClass.getConstructor( String.class, int.class, String.class, String.class, String.class, String.class );
System.out.println( "获取构造方法:" + constructor );
Person person = constructor.newInstance( "张三", 18, "a", "b", "c", "d" );
System.out.println( person );
Person person1 = personClass.newInstance();
System.out.println( person1 );
constructor.setAccessible( true );
}
@Test
public void reflexMethodTest() throws Exception {
System.out.println( "------------获取成员方法------------" );
Class<Person> personClass = Person.class;
System.out.println( "获取类对象:" + personClass );
Method eat = personClass.getMethod( "eat" );
Person person = new Person();
eat.invoke( person );
Method eat1 = personClass.getMethod( "eat", String.class );
eat1.invoke( person, "rain" );
System.out.println( "----------------------------------------" );
Method[] methods = personClass.getMethods();
for (Method method : methods) {
method.setAccessible( true );
System.out.println( "获取方法对象:" + method );
String name = method.getName();
System.out.println( "获取方法名称:" + name );
}
Field[] declaredFields = personClass.getDeclaredFields();
}
@Test
public void reflexClassNameTest() throws Exception {
System.out.println( "------------获取类名------------" );
Class<Person> personClass = Person.class;
System.out.println( "获取类对象:" + personClass );
String name = personClass.getName();
System.out.println( "获取类名:" + name );
}
}
import lombok.*;
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public void eat() {
System.out.println( "eat方法执行了..." );
}
public void eat(String foot) {
System.out.println( "eat方法执行了...foot:" + foot );
}
}