Java Class类与反射机制

java在运行时,为了确保每一个对象都能找到所属的类,一般会对每一个对象进行标识,称为运行时类型标识,又称RTTI,用来保存这些类型信息的类是Class类(每一个类,在被Jvm装载的时候,都会自动生成一个class类),这些标识放在一起,就生成了一个对象的“出处清单”,一方面,便于程序开发者更灵活的使用语言,另一方面,也有助于实现Java的一个重要的机制——反射机制;

简单的说,就是

1.Class也是Java的一个类(只不过这个类比较特殊,它没有公有的构造参数,因而不能被用户显式的创建,它只能由Jvm自动创建。)

2.当你创建一个类的时候,系统会自动创建一个Class的对象,用来记录这个类的类型信息。(比如说,你创建了一个Student类,这时候,系统会生成一个Class类的对象,储存Student的内容,如果Student创建了两个对象,那么这两个对象会共用同一个Class类),如图:

3.Class的对象的数量和系统加载的类(包括自己定义的类和系统类库中的类)的数量相同,而且一一对应,而不是和系统中当前存在的对象一一对应。

简单介绍完了Class,我们再来介绍一下Java的一个重要的机制:反射,

  什么是反射?反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制主要的功能是什么?反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类;

在运行时调用任意一个对象的方法;

生成动态代理;

在运行时构造任意一个类的对象;  

在运行时判断任意一个类所具有的成员变量和方法;

话不多说,上一段代码:

package java反射机制;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestReflect {
   String a="show a parameter";
   public void get(){
	   System.out.println("show a method!");
   }
   public static void main(String[] args)  {
	 Class
   
    cl=null;
	 
	 try {
		 cl=Class.forName("java反射机制.TestReflect");
		Object obj=cl.newInstance();
		TestReflect te=(TestReflect)obj;
		System.out.println(te.a);
		
		//test to get a method
		Method me=cl.getMethod("get");
		me.invoke(cl.newInstance());
		
		
		
	} catch (InstantiationException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (NoSuchMethodException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (IllegalArgumentException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	}
}
}
这段代码比较简短,相信大家都能看的懂,那么就具体讲解一下,这其中的Java代码的解释
先定义一个class类的声明,然后让这个声明指向我们当前Java项目下的“Java反射机制”包下的“TestReflect”类,也就是说,当程序运行的时候,“TestReflect”类被JVM装载,自动生成了一个Class对象,然后,我们定义的cl声明,指向这个Class对象。
随后 cl.newInstance()方法可以生成一个“ TestReflect”的对象。我们用Object类的一个声明来指向这个实例,然后再强制转型,这时候转型得到的te就是一个正常的 TestReflect实例了。
然后我们尝试去输出这个对象的参数,即System.out.println(te.a);
随后的三行代码是在尝试通过类名,生成对象,然后直接调用这个对象的方法,同上,这里不再累述。

可能有朋友会问:"这样编程有什么好处呢?原本一行代码“TestReflect rr=new TestReflect();”就能解决的问题,现在要搞得这么复杂?" 这里当然是由它的好处的,当我们编写大型程序的时候,反射机制可以帮助我们事先动态装载(先前我们使用的“TestReflect rr=new TestReflect();”是一种静态编程,即在编写程序的那一刻,就已经决定了程序编译的过程,,也就是说假如程序在运行到第二步的时候,我们的编译工作可能执行到第五补了,借助反射机制,我们可以提前告诉JVM应该加载哪些类的信息,这么一来,我们就实现了动态装载,也就是说JVM的编译内容是运行的情况来确定的,而不是一开始就定义好的。

这么一来,我们就可以实现程序模块之间的松散耦合,提高代码的运行效率即我们只装载了我们需要的类,减轻了JVM的工作量,(而这只是其中的一个优点),提高了程序的灵活性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值