reflect 反射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/QuietHRH/article/details/82262345

domain


public class Student {
	private String name; // 姓名
	private int age; // 年龄
	private String description; // 描述
	
	
	public Student() {
		System.out.println("--------------调用无参构造方法(public)-------------------");
	}
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
		System.out.println("--------------调用两个参数的构造方法(public)-------------------");
	}
	
	private Student(String name, int age, String description) {
		this.name = name;
		this.age = age;
		this.description = description;
		
		System.out.println("--------------调用三个参数的构造方法(private)-------------------");
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	
	// 私有方法
	private String show(int num) {
		System.out.println("----------调用private show方法----------");
		return "show : " + num;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", description=" + description + "]";
	}
	
}

Class



public class ClassTest {
	@Test
	public void demo1() throws Exception{
		// 需求: 获取student类的 Class对象, 就可以获取构造方法对象, 属性对象, 方法对象
		
		// 方式一: Class.forName(包名 + 类名);
		// 应用场景: 配置文件(如 jdbc.properties)
		Class<?> clazz = Class.forName("cn.itcast.domain.Student");
		System.out.println(clazz);
		
		// 方式二: 类名.class
		// 应用场景: 如 new BeanHandler<Order>(Order.class)
		Class<?> clazz2 = Student.class;
		System.out.println(clazz2);
		
		// 方式三: 对象名.getClass();
		// 应用场景: 获取new的对象以后, 一般出现在 执行方法中
		Student s = new Student();
		System.out.println(s.getClass());
	}
}

Constructor



public class ConstructDemo {
	@Test
	public void demo1(){
		// 需求: 常规 new 对象方法
		// 1 调用有参数构造
		Student student = new Student("张三", 18);
		// System.out.println(student);
		
		// 2 调用无参数构造
		Student student2 = new Student();
		
		// 3 调用私有构造方法 // 不能通过编译,不能调用
		// Student student3 = new Student("张三", 18, "我是一个好人...");
	}
	
	@Test
	public void demo2() throws Exception{
		// 需求: 通过反射 调用 有参数构造
		// 套路: 获取指定类的Class对象, 获取对象的构造方法, 调用构造方法
		// 1 获取指定类的Class对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		// 2 获取构造方法对象
		Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
		// 3 调用构造方法
		Object student2 = constructor.newInstance("李四", 36);
		System.out.println(student2);
	}
	
	@Test
	public void demo3() throws Exception{
		// 需求: 通过反射 调用 无参数构造
		// 套路: 获取指定类的Class对象, 获取对象的构造方法, 调用构造方法
		// 1 获取指定类的Class对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		// 2 获取构造方法对象
		Constructor<?> constructor = clazz.getConstructor();
		// 3 调用构造方法
		Object student2 = constructor.newInstance();
		System.out.println(student2);
	}
	
	@Test
	public void demo4() throws Exception{
		// 需求: 通过反射 调用 无参数构造(简化版)
		// 套路: 获取指定类的Class对象, 获取对象的构造方法, 调用构造方法
		// 1 获取指定类的Class对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		// 3 调用构造方法
		Object student2 = clazz.newInstance();
		System.out.println(student2);
	}
	
	@Test
	public void demo5() throws Exception{
		// 需求: 通过反射 调用 私有的有参数构造
		// 套路: 获取指定类的Class对象, 获取对象的构造方法, 调用构造方法
		// 1 获取指定类的Class对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		// 2 获取构造方法对象
		// Constructor<?> constructor = clazz.getConstructor(String.class, int.class, String.class); // 获取公共的(public)
		Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class, String.class);// 获取私有的(private)
		// 4 设置可以访问私有方法: 默认开关关闭, 打开
		constructor.setAccessible(true);
		// 3 调用构造方法
		Object student2 = constructor.newInstance("王五", 36, "我是一个好人...");
		System.out.println(student2);
	}
}

Field



public class FieldTest {
	@Test
	public void demo1(){
		// 需求: 常规方式调用属性 对象名.属性 [= 值]
		// 1 创建对象
		Student student = new Student();
		
		// 2 设置属性值(因为是私有的,所以不能调用)
		// student.name = "";
		
		// 3 获取属性值(因为是私有的,所以不能调用)
		// System.out.println(student.name);
	}
	
	@Test
	public void demo2() throws Exception{
		// 需求: 通过反射方式调用属性 
		// 1 创建对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		Student student = (Student) clazz.newInstance();
		
		// 2 设置属性值(因为是私有的,所以不能调用)
		// student.name = "";
		Field nameField = clazz.getDeclaredField("name");
		// 2.1 必须开启访问
		nameField.setAccessible(true);
		// 2.2 设置属性值
		nameField.set(student, "凤姐");
		
		System.out.println(student);
		
		// 3 获取属性值(因为是私有的,所以不能调用)
		// System.out.println(student.name);
		String name = (String) nameField.get(student);
		System.out.println(name);
	}
}

Method



public class MethodTest {
	@Test
	public void demo1(){
		// 需求: 常规调用 get和set方法
		// 1 创建对象
		Student student = new Student();
		
		// 2 调用set方法 
		student.setName("赵六");
		student.setAge(16);
		System.out.println(student);
		
		// 3 调用get方法
		System.out.println(student.getName());
		System.out.println(student.getAge());
		
		// 4 不能调用私有方法
		// student.show(3);
	}
	
	@Test
	public void demo2() throws Exception{
		// 需求: 通过反射调用 get和set方法(public)
		// 1 创建对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		Student student = (Student) clazz.newInstance();
		
		// 2 调用set方法 
		// student.setName("赵六11");
		Method setNameMethod = clazz.getMethod("setName", String.class);
		setNameMethod.invoke(student, "赵云");
		
		// student.setAge(161);
		Method setAgeMethod = clazz.getMethod("setAge", int.class);
		setAgeMethod.invoke(student, 16);
		
		System.out.println(student);
		
		// 3 调用get方法
		// String name = student.getName();
		Method getNameMethod = clazz.getMethod("getName");
		String name = (String) getNameMethod.invoke(student);
		System.out.println(name);
	}
	
	@Test
	public void demo3() throws Exception{
		// 需求: 通过反射调用 show方法(private)
		// 1 创建对象
		Class<?> clazz = Class.forName("cn.hrh.domain.Student");
		Student student = (Student) clazz.newInstance();
		
		// 2 调用私有方法: private String show(int num)
		Method showMethod = clazz.getDeclaredMethod("show", int.class);
		
		// 3 设置成可以访问
		showMethod.setAccessible(true);
		
		// 4 调用
		String returnVal = (String) showMethod.invoke(student, 5);
		System.out.println(returnVal);
		
	}
}

测试静态主函数

public class Test {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
    }
}
 @Test
    public void test() throws Exception {

        Class<?> clazz = Class.forName("com.domain.Test");

        Method mainMethod = clazz.getMethod("main", new Class[]{String[].class});

       	mainMethod.invoke(null, new Object[]{new String[]{"你好啊", "主函数"}});


    }

猜你喜欢

转载自blog.csdn.net/QuietHRH/article/details/82262345