java的反射机制

java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息以及动态调用对象的方法的功能成为java语言的反射机制。(动态获取类中的信息,就是java反射,也可以称为对类的解剖)

想要对字节码文件进行解剖,就必须要有字节码文件对象。下面介绍三种方法获取字节码文件对象:

  • 使用Object类中的getClass()方法:必须明确具体的类并创建对象。(比较麻烦)
public static void getClassObject_1() {
		Person p = new Person();
		Class clazz = p.getClass();
		
		Person p1 = new Person();
		Class clazz1 = p.getClass();
		System.out.println(p == p1);//false
		System.out.println(clazz == clazz1);//true
	}
  • 使用类中的静态属性.class来获取类对象:需要知道类名,并调用类中的静态成员。
public static void getClassObject_2() {
		Class clazz = Person.class;
		Class clazz1 = Person.class;
		
		System.out.println(clazz == clazz1);//true
	}
  • 只要通过给定类的字符串名就可以获取该类:使用class类中的方法完成,forName()方法。更方便。
public static void getClassObject_3() throws ClassNotFoundException {
		
		//String className = "Person";//报错,类名错误,类名需要完整,包括所有的包,java.lang.ClassNotFoundException: Person
		String className = "cn.itcast.bean.Person";
		Class clazz = Class.forName(className);
		System.out.println(clazz);
	}
  • 反射机制的使用实例:

    1、产生该类的对象

public static void createNewObject()
			throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		/*
		 * 早期:new的时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
		 * 并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象。
		 */
                //cn.itcast.bean.Person p = new cn.itcast.bean.Person();
		
		//现在:
		String name = "cn.itcast.bean.Person";
		
		//找寻该名称类文件,并加载进内存,并产生class对象。
		Class clazz = Class.forName(name);
		
		//如何产生该类的对象呢?
		Object obj = clazz.newInstance();//如果类中无空参构造函数,则会报出异常,此方法只适用于类中有空参构造函数的情况。
	}	
public static void createNewObject_2() throws ClassNotFoundException, Exception, SecurityException {
//		cn.itcast.bean.Person p = new cn.itcast.bean.Person("xiaoqiang", 38);
		/*
		 * 当获取指定名称对应类中的所体现的对象时,
		 * 对该对象初始化不使用空参数构造该怎么办?
		 * 既然是通过指定的构造函数进行对象的初始化,
		 * 所以应该先获取到该构造函数,通过字节码文件对象即可完成。
		 * 该方法是:getConstructor(paramterTypes);
		 * 
		 */
		
		String name = "cn.itcast.bean.Person";
		//找寻该名称类文件,并加载进内存,并产生class对象。
		Class clazz = Class.forName(name);	
		//获取到了指定的构造函数对象
		Constructor constructor = clazz.getConstructor(String.class, int.class);//String.class和int.class表示类中Sting和int型的字节码文件
		
		//通过该构造器对象的newInstance方法进行对象的初始化。
		Object obj = constructor.newInstance("xiaoming", 28);
		
	}

    2、获取字节码文件中的字段

public static void getFieldDemo() throws Exception {
		Class clazz = Class.forName("cn.itcast.bean.Person");
//		Field field = clazz.getField("name");//只能获取公有的字段
		Field field = clazz.getDeclaredField("age");//凡是加declared的方法都能够获取类中所有的成员。包括私有成员。
		System.out.println(field);
		
		//对私有字段的访问取消权限检查。暴力访问
		field.setAccessible(true);
		Object obj = clazz.newInstance();
		field.set(obj, 89);
		Object o = field.get(obj);
		
		System.out.println(o);
	}

    3、获取类的方法

        //获取有参数的方法并调用
	public static void getMethodDemo_3() throws Exception {
		Class clazz = Class.forName("cn.itcast.bean.Person");
		Method method = clazz.getMethod("paramMethod", String.class, int.class);		
		Object obj = clazz.newInstance();
		method.invoke(obj, "xioqiang",23);
		
	}		
	
	//获取单个方法并调用方法
	public static void getMethodDemo_2() throws Exception {
		Class clazz = Class.forName("cn.itcast.bean.Person");
		Method method = clazz.getMethod("show", null);//获取方法需要传递方法名称和参数,获取空参数一般方法。		
		//Object obj = clazz.newInstance();
		Constructor constructor = clazz.getConstructor(String.class, int.class);		
		Object obj = constructor.newInstance("xiaoming",23);
		method.invoke(obj, null);		
	}
	// 获取指定class中的所有公共函数
	public static void getMethodDemo() throws Exception {
		Class clazz = Class.forName("cn.itcast.bean.Person");		
		//Object obj = clazz.newInstance();
		//Method[] methods = clazz.getMethods();//获取的都是public方法,包含父类object中的方法
		Method[] methods = clazz.getDeclaredMethods();//可以获取任何权限的方法。只获取本来中所有方法,包含私有。
		for(Method method : methods){
			System.out.println(method);
		}
		
	}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值