Java反射机制详解

本文较为详细的分析了Java反射机制。分享给大家供大家参考,具体如下:

一、预先需要掌握的知识(java虚拟机)

java虚拟机的方法区:

java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区。方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中。这些信息主要包括:

1、这个类型的全限定名

2、这个类型的直接超类的全限定名

3、这个类型是类类型还是接口类型

4、这个类型的访问修饰符

5、任何直接超接口的全限定名的有序列表

6、该类型的常量池

7、字段信息

8、方法信息

9、除了常量以外的所有类变量

10、一个到class类的引用

等等(读者可以参考《深入java虚拟机》这本书的叙述)

Class类:

Class类是一个非常重要的java基础类,每当装载一个新的类型的时候,java虚拟机都会在java堆中创建一个对应于新类型的Class实例,该实例就代表此类型,通过该Class实例我们就可以访问该类型的基本信息。上面说到在方法区中会存储某个被装载类的类型信息,我们就可以通过 Class实例来访问这些信息。比如,对于上面说到的信息Class中都有对应的方法,如下:

1、getName();这个类型的全限定名

2、getSuperClass();这个类型的直接超类的全限定名

3、isInterface();这个类型是类类型还是接口类型

4、getTypeParamters();这个类型的访问修饰符

5、getInterfaces();任何直接超接口的全限定名的有序列表

6、getFields();字段信息

7、getMethods();方法信息

等等(读者可以自己参看jdk帮助文档,得到更多的信息)

二、java反射详解

反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到JVM中的类的内部信息,允许您执行程序时才得到需要类的内部信息,而不是在编写代码的时候就必须要知道所需类的内部信息,这使反射成为构建灵活的应用的主要工具。

反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代 表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class类中针对这三个元素的方法:

1、得到构造器的方法

Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,

Constructor[] getConstructors() -- 获得类的所有公共构造函数

Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)

Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)

2、获得字段信息的方法

Field getField(String name) -- 获得命名的公共字段

Field[] getFields() -- 获得类的所有公共字段

Field getDeclaredField(String name) -- 获得类声明的命名的字段

Field[] getDeclaredFields() -- 获得类声明的所有字段
3、获得方法信息的方法

Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法

Method[] getMethods() -- 获得类的所有公共方法

Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法

Method[] getDeclaredMethods() -- 获得类声明的所有方法

应用反射的基本步骤:

1、获得你想操作的类的Class对象;

方法一:Classc=Class.forName("java.lang.String") //这种方式获得类的Class对象需要 包名.类名

方法二:对于基本数据类型可以用形如Class c=int.class或Class c=Integer.TYPE的语句

方法三:Class c=MyClass.class

2、调用Class中的方法得到你想得到的信息集合,如调用getDeclaredFields()方法得到类的所有属性;

3、处理第2步中得到的信息,然后进行你想做的实际操作。

反射实例:

下面我将针对类的构造器、属性和方法分别举三个例子,向大家演示一下反射的应用过程。

1、构造器

步骤为:通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例

import java.lang.reflect.*;
public class ConstructorDemo{
  public ConstructorDemo(){ }
  public ConstructorDemo(int a, int b){
   System.out.println("a="+a+"b="+b);
  }
  public static void main(String args[]){
    try {
      Class cls =Class.forName("包名.ConstructorDemo");
      Class partypes[] =new Class[2]; partypes[0] = Integer.TYPE;
      partypes[1] =Integer.TYPE;
      Constructor ct=cls.getConstructor(partypes);
      Object arglist[] =new Object[2];
      arglist[0] = newInteger(37);
      arglist[1] = newInteger(47);
      Object retobj = ct.newInstance(arglist);
     } catch (Throwable e) {
      System.err.println(e);}
     }
  }

2、属性

步骤为:通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值

import java.lang.reflect.*;
public class FieldDemo1{
 public double d;
 public static void main(String args[]){
 try {
  Class cls = Class.forName("FieldDemo1");
  Field fld = cls.getField("d");
  FieldDemo1 fobj = new FieldDemo1();
  System.out.println("d = " + fobj.d);
  fld.setDouble(fobj, 12.34);
  System.out.println("d = " + fobj.d);
 } catch (Throwable e){
  System.err.println(e); }
 }
}

3、方法

步骤为:通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法

//通过使用方法的名字调用方法
import java.lang.reflect.*;
public class MethodDemo1{
 public int add(int a, int b){
 return a + b;
 }
 public static void main(String args[]){
  try {
   Class cls =Class.forName("MethodDemo1");
   Class partypes[] = new Class[2];
   partypes[0] = Integer.TYPE;
   partypes[1] = Integer.TYPE;
   Method meth = cls.getMethod("add",partypes);
   MethodDemo1 methobj = new MethodDemo1();
   Object arglist[] = new Object[2];
   arglist[0] = new Integer(37);
   arglist[1] = new Integer(47);
   Object retobj= meth.invoke(methobj, arglist);
   Integer retval = (Integer)retobj;
   System.out.println(retval.intValue());
  } catch (Throwable e) {
   System.err.println(e);
  }
 }
}

三、java反射的应用(Hibernate)

我们在第二部分中对java反射进行了比较系统的阐述,也举了几个简单的实例,下面我们就来讨论一下java反射的具体应用。前面我们已经知 道,Java反射机制提供了一种动态链接程序组件的多功能方法,它允许程序创建和控制任何类的对象(根据安全性限制)之前,无需提前硬编码目标类。这些特 性使得反射特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。下面我们就已 Hibernate框架为例像大家阐述一下反射的重要意义。

Hibernate是一个屏蔽了JDBC,实现了ORM的java框架,利用该框架我们可以抛弃掉繁琐的sql语句而是利用Hibernate中 Session类的save()方法直接将某个类的对象存到数据库中,也就是所涉及到sql语句的那些代码Hibernate帮我们做了。这时候就出现了 一个问题,Hibernate怎样知道他要存的某个对象都有什么属性呢?这些属性都是什么类型呢?如此,它在向数据库中存储该对象属性时的sql语句该怎么构造呢?解决这个问题的利器就是我们的java反射!

下面我们以一个例子来进行阐述,比如我们定义了一个User类,这个User类中有20个属性和这些属性的get和set方法,相应的在数据库中 有一个User表,这个User表中对应着20个字段。假设我们从User表中提取了一条记录,现在需要将这条记录的20个字段的内容分别赋给一个 User对象myUser的20个属性,而Hibernate框架在编译的时候并不知道这个User类,他无法直接调用myUser.getXXX或者 myUser.setXXX方法,此时就用到了反射,具体处理过程如下:

1、根据查询条件构造PreparedStament语句,该语句返回20个字段的值;

2、Hibernate通过读取配置文件得到User类的属性列表list(是一个String数组)以及这些属性的类型;

3、创建myUser所属类的Class对象c;c=myUser.getClass();

4、构造一个for循环,循环的次数为list列表的长度;

4.1、读取list[i]的值,然后构造对应该属性的set方法;

4.2、判断list[i]的类型XXX,调用PreparedStament语句中的getXXX(i),进而得到i出字段的值;

4.3、将4.2中得到的值作为4.1中得到的set方法的参数,这样就完成了一个字段像一个属性的赋值,如此循环即可;

看到了吧,这就是反射的功劳,如果没有反射很难想象如果完成同样的功能会有多么难!但是反射也有缺点,比如性能比较低、安全性比较复杂等,这里就不在讨论这些东西,感兴趣的读者可以在网上找到答案,有很多的!

希望本文所述对大家Java程序设计有所帮助。

(0)

相关推荐

  • Java基础--反射机制

    反射 反射可以使我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码链接.反射允许我们在编写和执行时,使我们的代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码. 反射机制作用 反编译:.class -> .java 通过反射机制访问Java对象的属性,方法,构造方法 反射的使用 反射机制获取类的三种方式 Class c1 = Class.forName("com.webb.basis.reflect.Demo"); // 一般采

  • Java 反射机制详解及实例代码

    Java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 package Reflect; /** * 通过一个对象获得完整的包名和类名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args) {

  • java 反射机制

    本文导引: 通过反射机制 获取类的基本信息 获取类的注解信息 获取泛型信息 package reflection; @AnnotationUserTable("datebaseExample") public class User { @AnnotationUserField(uName="name",type="varchar",length=10) private String name; @AnnotationUserField(uName

  • 简单总结Java的反射机制的运用

    Java 的反射机制是使其具有动态特性的非常关键的一种机制,也是在JavaBean 中广泛应用的一种特性. 简单来说,一个类或者一个对象是拥有下面几种属性的: Method,Constructor,Field,其大致结构类图如下: 我们现在用代码来说明问题: 首先,我们看Class类,在Class类中,我们可以看见下面的几个重要的方法: getInterfaces() getSuperClass(); isInterface(); 这是用来得到一个类的接口或者超类,以及判断这个类是不是一个接口:

  • Java 反射机制知识详细介绍及总结

    本篇将从以下几个方面讲述反射的知识: class 的使用 方法的反射 构造函数的反射 成员变量的反射 一.什么是class类 在面向对象的世界里,万物皆对象.类是对象,类是java.lang.Class类的实例对象.另外class类只有java虚拟机才能new出来.任何一个类都是Class 类的实例对象.这实例对象有三种表达方式: public class User{ } public class ClassTest{ User u=new User(); //方式1: Class c1=Use

  • Java 反射机制详解及实例

    Java 反射机制详解及实例 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!            一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高

  • Java学习之反射机制及应用场景介绍

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框架都或多或少的用到Java的反射机制. 什么是Java反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的以及动态调用对象的方法的功能称为Java的反射机制. 反射机制提供了哪些功能? 在运行时判定

  • Java反射机制详解_动力节点Java学院整理

    一.先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下看. 二.反射机制的作用: 1.反编译:.class-->.java 2.通过反射机制访问java对象的属性,方法,构造方法等: 这样好像更容易理解一些,下边我们具

  • 老生常谈Java反射机制(必看篇)

    什么是反射机制 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作.例如它允许一个java的类获取他所有的成员变量和方法并且显示出来.这个能特定我们不常看到,但是在其他的比如C或者C++语言中很不就存在这个特性.一个常见的例子是在JavaBean中,一些组件可以通过一个构造器来操作.这个构造器就是用的反射在动态加载的时候来获取的java中类的属性的. 主要的类 Class 类的实例表示正在运行的 Java 应用程序中的类和接口.Class没

  • Java反射机制详解

    本文较为详细的分析了Java反射机制.分享给大家供大家参考,具体如下: 一.预先需要掌握的知识(java虚拟机) java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 1.这个类型的全

  • Java中的反射机制详解

    Java中的反射机制详解 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下

  • Java动态代理和反射机制详解

    反射机制 Java语言提供的一种基础功能,通过反射,我们可以操作这个类或对象,比如获取这个类中的方法.属性和构造方法等. 动态代理:分为JDK动态代理.cglib动态代理(spring中的动态代理). 静态代理 预先(编译期间)确定了代理者与被代理者之间的关系,也就是说,若代理类在程序运行前就已经存在了,这种情况就叫静态代理 动态代理 代理类在程序运行时创建的代理方式.也就是说,代理类并不是在Java代码中定义的,而是在运行期间根据我们在Java代码中的"指示"动态生成的. 动态代理比

  • Java基础篇之反射机制详解

    目录 1.反射概述 1.1什么是反射 1.2.反射能干什么 2.解剖类 2.1反射构造方法 2.1.1反射无参的构造函数 2.1.2反射“一个参数”的构造函数 2.1.3反射“多个参数”的构造函数 2.1.4反射“私有”的构造函数 2.1.5反射得到类中所有的构造函数 2.2反射类中的方法 2.3反射类中的属性字段 思考:在讲反射之前,先思考一个问题,java中如何创建一个对象,有哪几种方式? Java中创建对象大概有这几种方式: 1.使用new关键字:这是我们最常见的也是最简单的创建对象的方式

  • Java反射技术详解及实例解析

    前言 相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有个开源框架jOOR相信很多人都用过,不过我们还是要学习反射的基础语法,这样才能自己写出优秀的框架,当然这里所讲的反射技术,是学习Android插件化技术.Hook技术等必不可少的! 一.基本反射技术   1.1 根据一个字符串得到一个类 getClass方法 String nam

  • JAVA SPI机制详解使用方法

    目录 写在前面 什么是SPI 使用场景 实现约定 四种角色 基于JAVA原生特性实现的JAVA SPI机制的DEMO 1. 主要角色 2. 示例代码 3. 说明 基于SPRING BOOT实现的JAVA SPI机制的DEMO 写在前面 Java SPI提供了一种为某个接口寻找服务实现的机制.有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,SPI的核心思想就是解耦. 什么是SPI SPI全称Service Provider Interface,是Java提供的

  • C++ 反射机制详解及实例代码

    C++ 反射机制 一.前言: Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用编译期间完全未知的classes.换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体.或对其fields设值.或唤起其methods.然而C++是不支持反射机制,虽然C++有RTTI(运行时类型识别).但是想要实现C++对象序列化,序列化就是存储到磁盘上,将对象变成一定格式的二

随机推荐