反射机制的解读

反射机制通俗理解:

Java反射机制是一个动态机制,允许我们在运行期决定实例化一个类,调用其方法,属性等操作而不是在编码期间确定。编码期间决定 好比 计划行事。反射带来的是动态期间决定,即运行过程中“见机行事”。反射中最重要的一个类:Class
Class的每一个实例用于表示JVM已经加载的一个类,所以Class的实例称为类对象。

JVM内部加载的每个类都有且只有一个Class实例与之对应。通过Class实例我们可以得知其表示的类的一切信息,比如:类名,有那些方法,属性等。

反射机制的解读_第1张图片

#1.反射机制的概念:

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

反射机制是在运行期间操作的,是通过jvm虚拟机编译,生成的.class文件后,

反射的作用1:获取类的类对象

当我们需要在程序运行期间操作某个类,那么要先获取这个类的类对象。
获取方式有三种:
1.每个类都有一个静态属性:class

例如:String.class,    Person.class
这个属性就是Class类型的,可以直接获取该类的类对象,但是缺点在于在编码期间确定获取某个类的类对象,不可更改。

2.Class提供了静态方法:

	Class.forName(String ClassName)
	指定参数获取给定类的类对象

3.通过类加载器ClassLoader。

反射的作用2:“见机行事”

假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。
Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。大家都用过Jcreator和eclipse。当我们构建出一个对象的时候,去调用该对象的方法和属性的时候。一按点,编译工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供用户进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审。

反射的作用3:获取对象的类信息

   获取一个类的访问修饰符、成员、方法、构造方法以及超类的信息.

   检获属于一个接口的常量和方法声明.

   创建一个直到程序运行期间才知道名字的类的实例.

   获取并设置一个对象的成员,甚至这个成员的名字是

在程序运行期间才知道.

   检测一个在运行期间才知道名字的对象的方法

使用反射的步骤:

1.先导入java.lang.relfect 包

遵循三个步骤
第一步是获得你想操作的类的 java.lang.Class 对象
第二步是调用诸如 getDeclaredMethods 的方法
第三步使用 反射API 来操作这些信息

获得Class对象的方法

如果一个类的实例已经得到,你可以使用

   【Class c = 对象名.getClass(); 】

  例: TextField t = new TextField();

          Class c = t.getClass();

          Class s = c.getSuperclass();

如果你在编译期知道类的名字,你可以使用如下的方法

Class c = java.awt.Button.class;
或者

     Class c = Integer.TYPE;

如果类名在编译期不知道, 但是在运行期可以获得, 你可以使用下面的方法

      Class c = Class.forName(strg);

这样获得Class类对象的方法,其实是利用反射API把指定字符串的类加载到内存中,所以也叫类加载器加载方法。这样的话,它会把该类的静态方法和静态属性,以及静态代码全部加载到内存中。但这时候,对象还没有产生。所以为什么静态方法不能访问非静态属性和方法。因为静态方法和属性产生的时机在非静态属性和方法之前。

反射的优缺点:

优点:
1:能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
2:与Java动态编译相结合,可以实现无比强大的功能

缺点:
1:使用反射的性能较低

2:使用反射相对来说不安全

3:破坏了类的封装性,可以通过反射获取这个类的私有方法和属性

简单案例(这个案例可以很好的理解反射):
利用反射机制,往一个泛型集合中添加元素。

	 * 怎么将100在执行期间设置进list集合?	
	 * 
	 * 	list.add(100);

public static void main(String[] args) throws Exception {
		ArrayList list = new ArrayList<>();
		list.add("one");
		list.add("two");

		
		Class cls = list.getClass();//先获取 Class对象
		/*
		 * 第一个参数:该对象的方法
		 * 
		 * 第二个参数: 该方法对象的参数列表类型,Object是所有类的父类,这里会自动泛型
		 */
		Method method = cls.getMethod("add", Object.class);//获取Class对象的方法
		/*
		 * invoke()
		 * 让一个方法对象动态执行
		 * 
		 * 第一个参数:想让谁(对象)的add方法动态执行
		 * 第二个参数:该方法动态执行期间,传入的实际参数
		 */
		method.invoke(list, 100);//通过invoke方法在运行期通过Class对象的方法传入参数

你可能感兴趣的:(java)