反射机制是Java特性之一,反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对大家以后学习框架技术有很大的帮助。

那么什么是Java的反射呢?

大家都知道,要让Java程序能够运行,那么就得让Java类要被Java虚拟机加载。Java类如果不被Java虚拟机加载,是不能正常运行的。现在我们运行的所有的程序都是在编译期的时候就已经知道了你所需要的那个类的已经被加载了。

Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类。这样的特点就是反射。

那么Java反射有什么作用呢?

假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。

Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。大家都用过Jcreator和eclipse。当我们构建出一个对象的时候,去调用该对象的方法和属性的时候。一按点,编译工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供用户进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审。

Class类

       要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。

反射API

       u反射API用于反应在当前Java虚拟机中的类、接口或者对象信息

u功能
—获取一个对象的类信息.

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

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

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

       —获取并设置一个对象的成员,甚至这个成员的名字是
   在程序运行期间才知道.

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

利用Java反射机制我们可以很灵活的对已经加载到Java虚拟机当中的类信息进行检测。当然这种检测在对运行的性能上会有些减弱,所以什么时候使用反射,就要靠业务的需求、大小,以及经验的积累来决定。

那么如何利用反射API在运行的时候知道一个类的信息呢?

代码示例:

[java] view plain copy print ?
  1. <span style="font-size:16px;">import java.lang.reflect.Field;
  2. import java.lang.reflect.Method;
  3. import javax.swing.JOptionPane;
  4. /**
  5. *本类用于测试反射API,利用用户输入类的全路径,
  6. *找到该类所有的成员方法和成员属性
  7. */
  8. public class MyTest {
  9. /**
  10. *构造方法
  11. */
  12. public MyTest(){
  13. String classInfo=JOptionPane.showInputDialog(null,"输入类全路径");//要求用户输入类的全路径
  14. try {
  15. Class cla=Class.forName(classInfo);//根据类的全路径进行类加载,返回该类的Class对象
  16. Method[] method=cla.getDeclaredMethods();//利用得到的Class对象的自审,返回方法对象集合
  17. for(Method me:method){//遍历该类方法的集合
  18. System.out.println(me.toString());//打印方法信息
  19. }
  20. System.out.println("********");
  21. Field[] field=cla.getDeclaredFields();//利用得到的Class对象的自审,返回属性对象集合
  22. for(Field me:field){ //遍历该类属性的集合
  23. System.out.println(me.toString());//打印属性信息
  24. }
  25. } catch (ClassNotFoundException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. public static void main(String[] args) {
  30. new MyTest();
  31. }
  32. }</span>
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
/***本类用于测试反射API,利用用户输入类的全路径,
*找到该类所有的成员方法和成员属性*/
public class MyTest {/***构造方法*/public MyTest(){String classInfo=JOptionPane.showInputDialog(null,"输入类全路径");//要求用户输入类的全路径try {Class cla=Class.forName(classInfo);//根据类的全路径进行类加载,返回该类的Class对象Method[] method=cla.getDeclaredMethods();//利用得到的Class对象的自审,返回方法对象集合for(Method me:method){//遍历该类方法的集合System.out.println(me.toString());//打印方法信息}System.out.println("********");Field[] field=cla.getDeclaredFields();//利用得到的Class对象的自审,返回属性对象集合for(Field me:field){ //遍历该类属性的集合System.out.println(me.toString());//打印属性信息}} catch (ClassNotFoundException e) {e.printStackTrace();}}public static void main(String[] args) {new MyTest();}
}

运行的时候,我们输入javax.swing.JFrame,那么运行结果如下:

public void javax.swing.JFrame.remove(java.awt.Component)

public void javax.swing.JFrame.update(java.awt.Graphics)

…………

********

public static final int javax.swing.JFrame.EXIT_ON_CLOSE

private int javax.swing.JFrame.defaultCloseOperation

…………

大家可以发现,类的全路径是在程序运行的时候,由用户输入的。所以虚拟机事先并不知道所要加载类的信息,这就是利用反射机制来对用户输入的类全路径来对类自身的一个自审。从而探知该类所拥有的方法和属性。

通过上面代码,大家可以知道编译工具为什么能够一按点就能列出用户当前对象的属性和方法了。它是先获得用户输入对象的字符串,然后利用反射原理来对这样的类进行自审,从而列出该类的方法和属性。

使用反射机制的步骤:

u导入java.lang.relfect 包

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

获得Class对象的方法

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

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

      例: TextField t = new TextField();

              Class c = t.getClass();

              Class s = c.getSuperclass();

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

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

         Class c = Integer.TYPE;

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

          Class c = Class.forName(strg);

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

代码示例:

[java] view plain copy print ?
  1. <span style="font-size:16px;">package  com;
  2. public class MyTest {
  3. public static void main(String[] args) {
  4. TestOne  one=null;
  5. try{
  6. Class  cla=Class.forName("com.TestOne");//进行com.TestOne类加载,返回一个Class对象
  7. System.out.println("********");
  8. one=(TestOne)cla.newInstance();//产生这个Class类对象的一个实例,调用该类无参的构造方法,作用等同于new TestOne()
  9. }catch(Exception e){
  10. e.printStackTrace();
  11. }
  12. TestOne two=new TestOne();
  13. System.out.println(one.getClass() == two.getClass());//比较两个TestOne对象的Class对象是否是同一个对象,在这里结果是true。说明如果两个对象的类型相同,那么它们会有相同的Class对象
  14. }
  15. }
  16. class TestOne{
  17. static{
  18. System.out.println("静态代码块运行");
  19. }
  20. TestOne(){
  21. System.out.println("构造方法");
  22. }
  23. }</span>
package  com;public class MyTest {public static void main(String[] args) {TestOne  one=null;try{Class  cla=Class.forName("com.TestOne");//进行com.TestOne类加载,返回一个Class对象System.out.println("********");one=(TestOne)cla.newInstance();//产生这个Class类对象的一个实例,调用该类无参的构造方法,作用等同于new TestOne()}catch(Exception e){e.printStackTrace();}TestOne two=new TestOne();System.out.println(one.getClass() == two.getClass());//比较两个TestOne对象的Class对象是否是同一个对象,在这里结果是true。说明如果两个对象的类型相同,那么它们会有相同的Class对象}
}class TestOne{static{System.out.println("静态代码块运行");}TestOne(){System.out.println("构造方法");}
}

以上代码过行的结果是:

静态代码块运行

***********

构造方法

构造方法

代码分析:

在进行Class.forName("com.TestOne")的时候,实际上是对com.TestOne进行类加载,这时候,会把静态属性、方法以及静态代码块都加载到内存中。所以这时候会打印出"静态代码块运行"。但这时候,对象却还没有产生。所以"构造方法"这几个字不会打印。当执行cla.newInstance()的时候,就是利用反射机制将Class对象生成一个该类的一个实例。这时候对象就产生了。所以打印"构造方法"。当执行到TestOne two=new TestOne()语句时,又生成了一个对象。但这时候类已经加载完毕,静态的东西已经加载到内存中,而静态代码块只执行一次,所以不用再去加载类,所以只会打印"构造方法",而"静态代码块运行"不会打印。

反射机制不但可以例出该类对象所拥有的方法和属性,还可以获得该类的构造方法及通过构造方法获得实例。也可以动态的调用这个实例的成员方法。

代码示例:

[java] view plain copy print ?
  1. <span style="font-size:16px;">package reflect;
  2. import java.lang.reflect.Constructor;
  3. /**
  4. *
  5. * 本类测试反射获得类的构造器对象,
  6. * 并通过类构造器对象生成该类的实例
  7. *
  8. */
  9. public class ConstructorTest {
  10. public static void main(String[] args) {
  11. try {
  12. //获得指定字符串类对象
  13. Class cla=Class.forName("reflect.Tests");
  14. //设置Class对象数组,用于指定构造方法类型
  15. Class[] cl=new Class[]{int.class,int.class};
  16. //获得Constructor构造器对象。并指定构造方法类型
  17. Constructor con=cla.getConstructor(cl);
  18. //给传入参数赋初值
  19. Object[] x={new Integer(33),new Integer(67)};
  20. //得到实例
  21. Object obj=con.newInstance(x);
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }
  27. class Tests{
  28. public Tests(int x,int y){
  29. System.out.println(x+"    "+y);
  30. }
  31. }</span>
package reflect;import java.lang.reflect.Constructor;/**** 本类测试反射获得类的构造器对象,* 并通过类构造器对象生成该类的实例**/
public class ConstructorTest {public static void main(String[] args) {try {//获得指定字符串类对象Class cla=Class.forName("reflect.Tests");//设置Class对象数组,用于指定构造方法类型Class[] cl=new Class[]{int.class,int.class};//获得Constructor构造器对象。并指定构造方法类型Constructor con=cla.getConstructor(cl);//给传入参数赋初值Object[] x={new Integer(33),new Integer(67)};//得到实例Object obj=con.newInstance(x);} catch (Exception e) {e.printStackTrace();}}}class Tests{public Tests(int x,int y){System.out.println(x+"    "+y);}
}

运行的结果是” 33    67”。说明我们已经生成了Tests这个类的一个对象。

Java反射机制的原理及作用相关推荐

  1. JAVA反射机制及其原理实现

    9.1 概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:public.protected.private. OO ...

  2. java反射机制的原理

    什么是java的反射: 1.在运行状态中,对于任何一个类,都能够知道这个类的所有方法和属性. 2.对任意一个对象都能调用它的任何方法和属性. 这种动态获取信息和动态调用一个对象的方法和属性的机制就是j ...

  3. Java反射机制的原理和用途

    转:https://blog.csdn.net/Appleyk/article/details/77879073 看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依 ...

  4. java反射机制的原理与简单使用

    一. 原理 简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息.如果知道一个类的名称/或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法 ...

  5. Java反射机制的原理与使用(反编译)

    一. 原理 简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息.如果知道一个类的名称/或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法 ...

  6. java反射原理_java反射原理是什么?java反射机制原理详解

    前面给大家介绍了一下什么是java反射机制,那么下面要给大家介绍的就是java反射机制的原理,那么它的原理究竟是怎样的呢?下面就通过下面来做一下详细的了解吧. 首先我们再来介绍一下java反射机制. ...

  7. Java反射机制(简单易懂)

    文章目录 前言 一.反射机制 二.反射的用途 三.反射相关的类(重要) 3.1 Class类(反射机制的起源 ) 3.2 通过反射调用构造方法 3.3 通过反射调用普通方法 3.4 通过反射调用类属性 ...

  8. java反射机制原理,为什么需要反射,反射的作用

    最近在学java反射以及动态代理,好多博客都写的十分官方.就自己整合些资料.加深java反射机制的理解. 在说反射之前,我们要先了解动态语言和静态语言的概念: 动态类型语言 所谓动态类型语言,就是类型 ...

  9. Java反射及 IoC原理、内省机制

    JAVA反射及IoC原理.JAVA内省 1. 反射 反射是框架设计的灵魂,使用前提:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码文件). 1.1 反射概述 主要指程 ...

最新文章

  1. 图片像素、英寸、厘米之间的单位换算
  2. gevent源码初探-wsgi例子解析
  3. 项目管理中的需求变更和解决之道
  4. Oracle学习:数据的插入、修改和删除
  5. 如何将 winston log 库记录的日志写入 mongo DB 数据库
  6. 关于fixture.debugElement.query(By.css)这个方法的一个疑问
  7. mysql 5.7变化_从MySQL 5.5到5.7看复制的演进
  8. asp.net(c#) 将dbf转换为xls或wps,并将数据的列名改成中文;并判断本机是否安装office2003,2007和wps2007,2010...
  9. Java 字节和字符流的读写+Buffered
  10. 内联函数和宏定义的相关区别
  11. 【C/C++】最大公约数和最小公倍数(辗转相除、更相减损、stein)
  12. OpenGL 渲染 YUYV(YUV422)
  13. 电子商务B2C网店购物系统走势
  14. 计算机232接口接线,RS232串口接线原理介绍
  15. bzoj 1260涂色 题解
  16. win7显示安装程序正在启动服务器失败,Win7安装程序正在启动服务怎么办?
  17. Latex: 调整文档的行距?
  18. Win32 汇编 - 移位: SHL、SHR、SAL、SAR、ROL、ROR、RCL、RCR、SHLD、SHRD
  19. 谷粒学院(五)---Maven从入门到入魔
  20. DHCP的原理与配置

热门文章

  1. java的基本数据类型有什么特点,java八大基本数据类型
  2. 神经网络学习笔记(五) 径向基函数神经网络
  3. PC端安装android模拟器
  4. 基于天问block编译环境下ASRPRO语音芯片程序编写教程(一)软件下载与基础程序语句篇
  5. (附源码)计算机毕业设计Java二次元文化网站
  6. ps 的一些常见的键位技巧
  7. 在西安电子科技大学读研是一种什么样的体验
  8. 树莓派制作家用服务器,树莓派搭建家用小型NAS服务器
  9. mysql association_在mybatis的xml中添加association不生效
  10. 基于Ant的Mentions自定义公式功能