反射

反射是java的一种机制,对于任意一个类可以动态获取该类的对象和方法,对于任意一个对象,可以调用对象的属性或者方法。

说白了,就是有一个 Student 类,它有很多方法,对象,属性,构造方法。我在另一个类中想要获取并调用它的方法。必须把这个对象类中的方法,属性,构造方法包装成一个个对象,再根据自己的需要通过反射机制提供的方法【class.forName , getConstructor…】来获取对象类中的属性,方法。。。

package mylove.home.demo;
public class Student{//mylove.home.demo.Student
	//成员变量(属性)
	public String name;
	protected int age;
	private String six;

	public String getSix() {
		return six;
	}
	public void setSix(String six) {
		this.six = six;
	}
	Student(String str) {//默认构造方法

		System.out.println("默认构造方法"+str);
	}
	public Student() { //无参构造方法
		System.out.println("无参构造函数");

	}
	//有参构造方法(公有方法)
	public Student(char name) {
		System.out.println("姓名"+name);
	}

	public Student(char name,int age) {
		System.out.println("姓名"+name+"年龄"+age);
	}
    //(受保护的)实参构造方法
	protected Student(boolean n) {
		System.out.println("受保护的构造方法"+ n);
	}
	//(私有的)实参构造方法
	private Student(int age){
		System.out.println("我是私有的构造方法"+age);
	}
	public void show1(String s){
		System.out.println("调用了:公有的,String参数的show1(): s = " + s);
	}
	protected void show2(){
		System.out.println("调用了:受保护的,无参的show2()");
	}
	void show3(){
		System.out.println("调用了:默认的,无参的show3()");
	}
	private String show4(int age){
		System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " + age);
		return "abcd";
	}

}

1,获取类class对象的三种方式,如下(反射类):
方法三用的多 class.forName(“对象路径”)

package mylove.home.demo;
/**
 * 测试 通过反射获取类对象的三种实现方式 
 * @author Administrator
 */
public class TestReflect {
	public static void main(String[] args) {
		Student stu1 = new Student();
	    //方法一
		Class<? extends Student> class1 = stu1.getClass();  //获取类对象
		System.out.println("获取类对象 :"+class1.getName());
		
		//方法2
		Class<Student> class2 = Student.class;//获取类对象
		
		System.out.println(class1==class2); //true  class1与class2 获取的类对象是同一个
		
		//方法3  :一般这种方法使用比较多(.forName)
		try {
			Class class3 = Class.forName("mylove.home.demo.Student");//获取类对象
			System.out.println(class2 == class3);  //获取的类对象是同一个
		} catch (ClassNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}

,2,反射获取构造方法

1)通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员
2)获取构造方法
(批量获取)
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
3)(获取单个方法)
public Constructor getConstructor(Class… parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class… parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

package mylove.home.demo;

import java.lang.reflect.Constructor;

/**
 * 通过反射机制获取类的构造方法
 * @author RioNice#XWX
 *批量的方法:
 * 			public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
 * 		2).获取单个的方法,并调用:
 * 			public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
 * 			public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
 * 		
 * 			调用构造方法:
 * 			Constructor-->newInstance(Object... initargs)

*/
public class Constructors {
	public static void main(String[] args) throws Exception {
		//1,加载类对象
		Class<?> clazz = Class.forName("mylove.home.demo.Student");
		
		//获取所有公有构造方法
		System.out.println("..................所有的公有构造方法");
		
		Constructor<?>[] cs = clazz.getConstructors();
		for (Constructor<?> c : cs) {
			System.out.println(c);
		}
		
		System.out.println("---------获取所有的构造方法(私有,受保护的,公有)");
		Constructor<?>[] dc = clazz.getDeclaredConstructors();
		for (Constructor<?> cr : dc) {
			System.out.println(cr);
		}
		//System.out.println(dc);
		
		System.out.println("获取公有的 ==========无参的构造方法");
		Constructor<?> ct = clazz.getConstructor(null);
		System.out.println(ct);
		
		System.out.println("获取私有构造方法,并调用===============");
		Constructor<?> con = clazz.getDeclaredConstructor(char.class);
		System.out.println(con);
		
		//调用构造方法
//		con.setAccessible(true);//暴力服务
//		con.newInstance("男");
		/*
		 * 总结:这个类为了练习通过反射机制提供的方法来获取类的构造方法
		 * 		
		 *  */
	}

}

3,反射获取成员变量

获取成员变量并调用:
1.批量的
1).Field[] getFields():获取所有的"公有字段"
2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
2.获取单个的:
1).public Field getField(String fieldName):获取某个"公有的"字段;
2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)

	package mylove.home.demo;

import java.lang.reflect.Field;

/*
 * 获取成员变量并调用:
 * 
 * 1.批量的
 * 		1).Field[] getFields():获取所有的"公有字段"
 * 		2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
 * 2.获取单个的:
 * 		1).public Field getField(String fieldName):获取某个"公有的"字段;
 * 		2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
 * 
 * 	 设置字段的值:
 * 		Field --> public void set(Object obj,Object value):
 * 					参数说明:
 * 					1.obj:要设置的字段所在的对象;
 * 					2.value:要为字段设置的值;
 * 
 */

public class Fields {
	public static void main(String[] args) throws Exception {
		
			//1.获取Class对象
			Class stuClass = Class.forName("mylove.home.demo.Student");
			//2.获取字段
			System.out.println("************获取所有公有的字段********************");
			Field[] fArray = stuClass.getFields();
			//Field[] fieldArray = stuClass.getFields();
			for(Field f : fArray){
				System.out.println(f);
			}
			System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");
			fArray = stuClass.getDeclaredFields();
			for(Field f : fArray){
				System.out.println(f);
			}
			System.out.println("*************获取公有字段**并调用***********************************");
			Field f = stuClass.getField("name");
			System.out.println(f);
			//获取一个对象
			Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
			//为字段设置值
			f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"
			//验证
			Student stu = (Student)obj;
			System.out.println("验证姓名:" + stu.name);
			
			
			System.out.println("**************获取私有字段****并调用********************************");
			f = stuClass.getDeclaredField("six");
			System.out.println(f);
			f.setAccessible(true);//暴力反射,解除私有限定
			f.set(obj, "18888889999");
			System.out.println("验证电话:" + stu);
	}
}

4,反射获取对象方法

获取成员方法并调用:
1.批量的:
public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
2.获取单个的:
public Method getMethod(String name,Class<?>… parameterTypes):
参数:
name : 方法名;
Class … : 形参的Class类型对象
public Method getDeclaredMethod(String name,Class<?>… parameterTypes)

package mylove.home.demo;

import java.lang.reflect.Method;

/*
 * 获取成员方法并调用:
 * 
 * 1.批量的:
 * 		public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
 * 		public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
 * 2.获取单个的:
 * 		public Method getMethod(String name,Class<?>... parameterTypes):
 * 					参数:
 * 						name : 方法名;
 * 						Class ... : 形参的Class类型对象
 * 		public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
 * 
 * 	 调用方法:
 * 		Method --> public Object invoke(Object obj,Object... args):
 * 					参数说明:
 * 					obj : 要调用方法的对象;
 * 					args:调用方式时所传递的实参;
):
 */
public class MethodClass {
	public static void main(String[] args) throws Exception {
		//1.获取Class对象
		Class stuClass = Class.forName("mylove.home.demo.Student");
		//2.获取所有公有方法
		System.out.println("***************获取所有的”公有“方法*******************");
		stuClass.getMethods();
		Method[] methodArray = stuClass.getMethods();
		for(Method m : methodArray){
			System.out.println(m);
		}
		System.out.println("***************获取所有的方法,包括私有的*******************");
		methodArray = stuClass.getDeclaredMethods();
		for(Method m : methodArray){
			System.out.println(m);
		}
		System.out.println("***************获取公有的show1()方法*******************");
		Method m = stuClass.getMethod("show1", String.class);
		System.out.println(m);
		//实例化一个Student对象
		Object obj = stuClass.getConstructor().newInstance();
		m.invoke(obj, "刘德华");

		System.out.println("***************获取私有的show4()方法******************");
		m = stuClass.getDeclaredMethod("show4", int.class);
		System.out.println(m);
		m.setAccessible(true);//解除私有限定
		Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
		System.out.println("返回值:" + result);

	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值