Java反射机制的使用

反射这门技术在做一些比较通用的工具类的开发的时候,就非常有用了。
反射: 当一个class文件被加载到内存中的时候,那么jvm就会马上对该class文件的成员进行解剖,然后将class文件的成员数据封装到一个Class对象中
 ,我们如果可以获取到Class对象,那么我们就可以通过该Class对象来操作该类的所有成员。
话不多说。直接上代码。 微笑

获取Class对象的三种方法
@Test
	//获取Class对象的三种方法
	public void test1() throws Exception{
		//方式一:通过Class.forName获取Class对象。推荐使用.
		Class clazz1=Class.forName("com.shyleo.reflect.Person");
		System.out.println(clazz1);// class com.shyleo.reflect.Person
		
		//方式二:可以通过类名获取Class对象
		Class clazz2=Person.class;
		System.out.println(clazz2);// class com.shyleo.reflect.Person
		
		//方式三:可以通过对象获取Class对象
		Class clazz3=new Person().getClass();
		System.out.println(clazz3);// class com.shyleo.reflect.Person
		
		// clazz1,clazz2,clazz3是同一个对象。因为class文件只会加载一次。而这个对象只在class文件在加载时创建。
		System.out.println(clazz1==clazz2);//true
		System.out.println(clazz1==clazz3);//true
		
	}

通过Class对象获取构造方法
@Test
	//通过Class对象获取构造方法
	public void test2() throws Exception{
		Class clazz=Class.forName("com.shyleo.reflect.Person");
		
		//Constructor类 是用于表述一个构造方法的
		//通过class对象找到所有的构造方法. 
		/*
		Constructor[] constructors=clazz.getConstructors();//只获取了公共的构造方法。
		Constructor[] declaredConstructors = clazz.getDeclaredConstructors();//获取一个类 的所有构造方法,包括私有的。
		for(Constructor constructor:declaredConstructors){
			System.out.println(constructor);
		}
		*/
		
		//获取单个构造方法
		/*
		Constructor constructor=clazz.getConstructor(String.class,int.class,String.class);
		//System.out.println(constructor);// public com.shyleo.reflect.Person(java.lang.String,int,java.lang.String)
		//通过Constructor对象创建对象
		Person p= (Person) constructor.newInstance("小明",23,"男");
		System.out.println(p);// 姓名:小明     年龄:23  性别:男
		*/
		
		//获取私有的构造方法
		/*
		Constructor constructor=clazz.getDeclaredConstructor(String.class);
		//设置构造方法的访问权限(暴力反射);
		constructor.setAccessible(true);
		Person p=(Person) constructor.newInstance("小李");
		System.out.println(p);// 姓名:小李     年龄:0  性别:null
		*/
	}


通过Class获取,创建对象
@Test
	//通过Class对象获取,创建对象
	public void test5() throws Exception{
		Class clazz=Class.forName("com.shyleo.reflect.Person");
		
		//方式一:这种方式只能获取无参构造方法
		/*
		Person p=(Person) clazz.newInstance();
		System.out.println(p);//姓名:null  年龄:0  性别:null
		*/
		
		//方式二:通过Constructor对象创建对象
		Constructor constructor=clazz.getConstructor(String.class,int.class,String.class);
		//System.out.println(constructor);// public com.shyleo.reflect.Person(java.lang.String,int,java.lang.String)
		//constructor的newInstance方法是这样的:   public T newInstance(Object... initargs)
		Person p= (Person) constructor.newInstance("小明",23,"男");
		System.out.println(p);// 姓名:小明  年龄:23  性别:男
	}


通过Class对象获取成员函数-----java.lang.reflect.Method类
@Test
	//通过Class对象获取成员函数----java.lang.reflect.Method类
	public void test3() throws Exception{
		Class clazz=Class.forName("com.shyleo.reflect.Person");	
		
		//获取所有的方法
		/*
		//Method[] methods =  clazz.getMethods();  // 获取所有公共 的方法,包括继承下来的方法。
		//Method[] methods = clazz.getDeclaredMethods(); //获取所有的方法,包括私有的,但是不包括继承下来的方法。 
		for(Method m : methods){
			System.out.println(m);
		}
		*/
		
		Person p=new Person("小明",23,"男");
		//获取单个方法
		/*
		//第一个参数是方法名, 第二参数是形参列表的数据类型。
		Method m=clazz.getMethod("eat", int.class,String[].class);
		//执行一个方法
		//第一个参数:方法的调用者对象, 第二参数: 方法执行所需要的参数。
		m.invoke(p,300,new String[]{"aaa","bbb"});
		
		Method m1=clazz.getMethod("sleep", int.class);//注意:public static void sleep(int hours){
		m1.invoke(null, 22); //sleep是静态方法
		*/
		
		//私有的方法
		Method m  = clazz.getDeclaredMethod("study", null);
		//设置方法的访问权限是可以访问
		m.setAccessible(true);
		m.invoke(p, null);
	}


通过Class对象获取一个类的成员变量----java.lang.reflect.Field类
@Test
	//通过Class对象获取一个类的成员变量----java.lang.reflect.Field类
	public void test4() throws Exception{
		Class clazz=Class.forName("com.shyleo.reflect.Person");	
		
		//获取该类的所有成员变量
		/*
		Field[] fields=clazz.getDeclaredFields();
		for(Field field:fields){
			System.out.println(field);
		}
		*/
		Person p=new Person("小明",23,"男");
		Field field=clazz.getDeclaredField("sex");
		field.setAccessible(true);
		field.set(p, "女");//给属性赋值
		System.out.println(p);// 姓名:小明     年龄:23  性别:女
		//field.get(p)是获取属性值
		System.out.println(field.get(p));// 女
	}

以上代码使用到的
Person类
package com.shyleo.reflect;

public class Person {
		
	String name;
	int age;
	private String sex;
	
	public  Person(String name,int age,String sex){
		this.name=name;
		this.age=age;
		this.sex=sex;
	}
	public     Person(){
		System.out.println("无参构造方法...");
	}
	private Person(String name){
		this.name=name;
	}
	
	public void eat(int num,String[] arr){
		System.out.println(name+"吃"+num+"斤");
	}
	
	public static void sleep(int hours){
		System.out.println("睡"+hours+"小时");
	}
	
	private void study(){
		System.out.println(name+"学习...");
	}
	
	@Override
	public String toString() {
		return "姓名:"+ this.name+"  年龄:"+this.age+"  性别:"+this.sex;
	}
	
}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值