`

java反射

    博客分类:
  • jvm
 
阅读更多

一、预先需要掌握的知识(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对象; 

     方法一:Class c=Class.forName("java.lang.String") 

     方法二:对于基本数据类型可以用形如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] = new Integer(37); 
           arglist[1] = new Integer(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反射 java反射 java反射java反射

    Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射机制提供了强大的能力,包括在运行时检查类的结构、创建对象实例、调用方法以及访问和修改字段值。...

    JAVA反射机制的入门代码

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...

    java反射,获取所有属性、方法以及List集合类

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建对象、获取类...

    JAVA 反射机制应用

    Java反射机制是Java语言提供的一种强大功能,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是java.lang.Class,它代表了运行时的类信息。通过Class对象,我们...

    java 反射得到某个方法

    在本文中,我们将深入探讨如何使用Java反射来获取并执行某个特定的方法。 首先,我们需要了解Java反射的基本概念。`java.lang.Class`类是反射的核心,它代表了Java中的每一个类。我们可以通过以下方式获取到一个...

    Java反射性能测试分析

    ### Java反射性能测试分析 #### 引言 Java反射机制是Java编程语言中一个强大的特性,它允许程序在运行时动态地访问、检测和修改类、接口、字段和方法等对象。然而,反射操作通常会引入额外的开销,这在性能敏感的...

    Java反射机制总结

    ### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...

    Java反射经典实例

    Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等信息,即使这些信息在编译时并未明确知晓。在Java中,反射通常通过`java.lang.Class`类和相关的API来实现。本实例将...

    反射实例-JAVA反射机制

    ### 反射实例—JAVA反射机制 #### 一、反射概念及原理 反射在计算机科学领域,特别是程序设计中,是指程序有能力访问、检测和修改其自身的结构和行为。这一概念最早由Smith于1982年提出,并迅速应用于各种编程语言...

    java反射.pdf

    ### Java反射机制详解 #### 一、什么是Java反射? Java反射是Java编程语言的一个特性,它允许运行时检查和操作程序结构(类、字段、方法等)。反射的主要用途包括但不限于:动态实例化对象、访问私有成员、调用...

    java 反射 调用私有方法(有参数私有方法)获取私有属性值

    Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这个能力使得开发者可以突破静态类型的束缚,实现一些在编译时期无法完成...

    java反射源代码

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有高度的灵活性,尤其在处理框架、插件系统以及元数据驱动...

    java 反射机制例子

    ### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至修改自身的状态和行为。这种能力一经提出,迅速成为了计算机科学领域的研究...

    java 反射 报错 no such method exception

    ### Java反射机制与NoSuchMethodException详解 在Java编程中,反射是一种强大的机制,允许程序在运行时检查和修改自身结构和行为。然而,当开发者尝试使用反射调用一个不存在的方法时,便会遇到`java.lang....

    java反射获取所有属性,获取所有get方法,包括子类父类

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建动态代理等。...

    利用java反射将json字符串转成对象.zip

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在给定的“利用java反射将json字符串转成对象”的主题中,我们将深入探讨如何借助反射机制将JSON...

    Java反射机制Demo

    ### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的...

    北大青鸟java反射机制

    Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念...

Global site tag (gtag.js) - Google Analytics