Java反射技术

Java反射技术

一、利用反射获取类的构造方法并为类实例化对象
1、加载类:Class.forName(“className”);其中className表示类的全名:包名.类名
2、利用Class对象的getConstructor()方法得到Constructor对象,并获取对应类的公有构造方法,利用getDeclaredConstructor()方法可以获取对应类的公有和私有构造方法;若是获取的是类的私有构造方法,需要使用Constructor对象的setAccessible(true)方法获得对私有构造方法的访问权限;
3、利用Constructor对象的newInstance()方法可以为该类实例化相应的对象;

import java.lang.reflect.Constructor;
import java.util.ArrayList;

public class Demo001 {

	public static void main(String[] args) throws Exception {
		getPersonConstructor();
		getPersonConstructor1();
		getPersonConstructor2();
		getPersonConstructor3();
	}

	//利用反射获取Person类的无参构造函数
	public static void getPersonConstructor() throws Exception {
		//1、加载Person类
		Class cla =  Class.forName("day01_Java增强.反射.Person");
		//2、获取Person类的构造方法
		Constructor constructor = cla.getConstructor();
		//3、利用Person类的构造方法创建Person对象
		Person p = (Person) constructor.newInstance();
	}
	
	//利用反射获取Person类的带参构造函数
	public static void getPersonConstructor1() throws Exception {
		//1、加载Person类
		Class cla =  Class.forName("day01_Java增强.反射.Person");
		//2、获取Person类的构造方法
		Constructor constructor = cla.getConstructor(String.class);
		//3、利用Person类的构造方法创建Person对象
		Person p = (Person) constructor.newInstance("Student");
	}
	
	//利用反射获取Person类的带参构造函数
	public static void getPersonConstructor2() throws Exception {
		//1、加载Person类
		Class cla =  Class.forName("day01_Java增强.反射.Person");
		//2、获取Person类的构造方法
		Constructor constructor = cla.getConstructor(String.class,int.class);
		//3、利用Person类的构造方法创建Person对象
		Person p = (Person) constructor.newInstance("Student",18);
	}
	
	//利用反射获取Person类的私有的构造函数
	public static void getPersonConstructor3() throws Exception {
		//1、加载Person类
		Class cla =  Class.forName("day01_Java增强.反射.Person");
		//2、获取Person类的构造方法
		Constructor constructor = cla.getDeclaredConstructor(ArrayList.class);
		//3、暴力反射,将私有成员的访问权限打开
		constructor.setAccessible(true);
		//4、利用Person类的构造方法创建Person对象
		Person p = (Person) constructor.newInstance(new ArrayList());
	}

}

class Person {
	private String name = "张三";
	private int age;
	public double salary;

	public Person() {
		System.out.println("public Person()");
	}

	public Person(String name) {
		System.out.println("public Person(String name)");
	}

	public Person(String name, int age) {
		System.out.println("public Person(String name, int age)");
	}

	private Person(ArrayList list) {
		System.out.println("private Person(ArrayList list)");
	}
	
	public void add() {
		System.out.println("public void add()");
	}
	
	private void add(int a, int b) {
		System.out.println("private void add(int a, int b)");
	}
	
	private static void add(String str) {
		System.out.println("private static void add(String str)");
	}
	
	public static void main(String args[]) {
		System.out.println("main.......");
	}
}

运行结果:
在这里插入图片描述

二、利用反射技术获取类的普通方法并调用
1、加载类:Class.forName(“className”);其中className表示类的全名:包名.类名
2、利用Class对象的getMethod()方法得到Method对象,并获取对应类的公有方法,利用getDeclaredMethod()方法可以获取对应类的公有和私有方法;若是获取的是类的私有方法,需要使用Method对象的setAccessible(true)方法获得对私有方法的访问权限;
3、利用Method对象的invoke()方法可以调用该方法;

import java.lang.reflect.Method;
/**
 * 利用反射获取类的普通方法并调用
 * @author WangYifeng
 *
 * 2018年9月22日下午10:54:50
 */
public class Demo002 {

	static Person p = new Person();
	
	public static void main(String[] args) throws Exception {
		getMethod();
		getMethod1();
		getMethod2();
	}

	public static void getMethod() throws Exception {
		//加载类
		Class cla = Class.forName("day01_Java增强.反射.Person");
		Method method = cla.getMethod("add", null);//第一个参数为方法名,后面为可变的参数列表,指明方法的形参列表
		method.invoke(p, null);//第一个调用方法的对象,后面为传递的实参
	}
	
	public static void getMethod1() throws Exception {
		//加载类
		Class cla = Class.forName("day01_Java增强.反射.Person");
		Method method = cla.getDeclaredMethod("add", int.class, int.class);
		method.setAccessible(true);
		method.invoke(p, 26, 13);
	}
	
	public static void getMethod2() throws Exception {
		//加载类
		Class cla = Class.forName("day01_Java增强.反射.Person");
		Method method = cla.getDeclaredMethod("add", String.class);
		method.setAccessible(true);
		method.invoke(null, " ");
	}
	
}

运行结果:
在这里插入图片描述
三、利用反射调用类中的main方法
注意:利用invoke()调用参数列表为数组的方法时,需要将想传递的数组对象用数组再封装一次,否则会报错java.lang.IllegalArgumentException: wrong number of arguments

import java.lang.reflect.Method;
/**
 * 利用反射获取类中的main方法
 * @author WangYifeng
 *
 * 2018年9月22日下午10:55:25
 */
public class Demo003 {

	static Person p = new Person();
	
	public static void main(String[] args) throws Exception {
		getMain();
	}

	public static void getMain() throws Exception {
		//加载类
		Class cla = Class.forName("day01_Java增强.反射.Person");
		Method method = cla.getMethod("main", String[].class);//第一个参数为方法名,后面为可变的参数列表,指明方法的形参列表
		//利用invoke()调用参数列表为数组的方法时,需要将想传递的数组对象用数组再封装一次,否则会报错java.lang.IllegalArgumentException: wrong number of arguments
		method.invoke(p, new Object[] {new String[] {"1122","11"}});//第一个调用方法的对象,后面为传递的实参
	}

}

运行结果:
在这里插入图片描述
四、利用反射获取类的成员变量
1、加载类:Class.forName(“className”);其中className表示类的全名:包名.类名
2、利用Class对象的getField()方法得到Field对象,并获取对应类的公有成员变量,利用getDeclaredField()方法可以获取对应类的公有和私有成员变量;若是获取的是类的私有成员变量,需要使用Field对象的setAccessible(true)方法获得对私有成员变量的访问权限;
3、利用Field对象的get()方法可以获取该变量的值,利用getType()方法可以获得该变量的类型,利用set()可以设置变量的值;

import java.lang.reflect.Field;
/**
 * 利用反射获取类中的main方法
 * @author WangYifeng
 *
 * 2018年9月22日下午10:55:25
 */
public class Demo004 {

	static Person p = new Person();
	
	public static void main(String[] args) throws Exception {
		getField();
		getField1();
	}

	//利用反射获取类的成员变量:private String name = "张三";
	public static void getField() throws Exception {
		//加载类
		Class cla = Class.forName("day01_Java增强.反射.Person");
		//获取私有成员变量
		Field field = cla.getDeclaredField("name");
		//利用反射获得对私有成员变量的访问权限
		field.setAccessible(true);
		//获取私有变量的值
		System.out.println(field.get(p));
		//获取私有变量的类型
		System.out.println(field.getType());
		//设置私有变量的值
		field.set(p, "李四");
		System.out.println(field.get(p));
		
	}

	//利用反射获取类的成员变量:public double salary;
	public static void getField1() throws Exception {
		//加载类
		Class cla = Class.forName("day01_Java增强.反射.Person");
		//获取私有成员变量
		Field field = cla.getField("salary");
		//获取私有变量的值
		System.out.println(field.get(p));
		//获取私有变量的类型
		System.out.println(field.getType());
		//设置私有变量的值
		field.set(p, 0.83);
		System.out.println(field.get(p));	
	}
	
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在向学生讲解Class.forName()方法的使用时,有时需要扩展讲解为什么这样书写的原理,于是,扩展讲解Java反射技术可以查看被监视类的方法(构造方法和普通方法)、公有属性的功能,以达到封闭功能的效果。该例子使用MyEclipse 5.5完成demo示例。其中,com.jb.arklis.app.DemoApplication类利用反射技术可以观察任何非静态类(比如java.lang.String, javax.swing.JFrame等类和自定义的类,比如com.jb.arklis.dao.BaseDAO)的普通方法、构造方法以公有属性,是一个非常有实用意义的显示类。 该示例没有使用泛型技术,所以不是很完美。不过只要你稍微修改一下,就可作为自己工程中比较好的封装工具类使用! 下载解压之后,使用MyEclipse 5.5导入,打开该工程,找到DemoApplication类,然后点击run菜单-->找到(x)Arguments,然后在Program arguments中输入: com.jb.arklis.dao.BaseDAO, 然后点击run按钮,如果一切正常,那么你会看到使用反射在DemoApplication类中呼叫了BaseDAO的returnTestValue(String name)方法。 我的代码注释非常详细,相信当你看完之后,一般来说,如果不是新手(非常菜的人),那么你应该学会使用反射技术来实现封装的动作了--也就是说,你的技术有了一个非常大的提高--如果你看完之后,参见该示例中另外的JDBC代码,然后能够实现对JDBC进一步的封装,使JDBC连接的使用步骤更简单的话! OK,Good luck!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值