`

Java语言的反射机制

阅读更多

在JAVA运行环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。

这种动态获取类的信息以及动态调用类的对象的方法的功能来自于Java语言的反射(Reflection)机制。

JAVA反射机制主要提供了以下功能:

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

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

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

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

 Reflection是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称(是指包名+类名)的class的内部信息,包括其modifiers(诸如public,static等等)、superclass(例如Object)、实现之interface(例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods

一般而言,开发者群社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言被称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,而C++,Java,C#不是动态语言。

尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映像、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括method定义,也就是不能获得方法里的具体代码),并生成其对象的实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ablility of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

在JDK中,主要由以下类来实现JAVA反射机制, 这些类都位于java.lang.reflect包中

1、Class类:代表一个类

2、Field类:代表类的成员变量(成员变量也称为类的属性)

3、Method类:代表类的方法

4、Constructor类:代表类的构造方法

5、Array类:提供了动态创建数组,以及访问数组的元素的静态方法

反射机制示例代码一、

java 代码
  1. package com.test.reflect;   
  2.   
  3. import java.lang.reflect.Method;   
  4.   
  5. public class ReflectTest {   
  6.   
  7.     public static void main(String[] args) throws Exception {   
  8.            
  9.         //加载并初始化命令行参数指定的类   
  10.         Class clazz = Class.forName(args[0]);//args[0]为:java.lang.String   
  11.            
  12.         //获得类的所有方法   
  13.         Method[] methods = clazz.getDeclaredMethods();   
  14.         for(Method method:methods)   
  15.         {   
  16.             System.out.println(method.toString());   
  17.         }   
  18.   
  19.     }   
  20.   
  21. }   

 

输出结果为:

public int java.lang.String.hashCode()
public int java.lang.String.compareTo(java.lang.String)
public volatile int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.indexOf(int,int)
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(java.lang.String)
public int java.lang.String.indexOf(java.lang.String,int)
static int java.lang.String.indexOf(char[],int,int,char[],int,int,int)
public boolean java.lang.String.equals(java.lang.Object)
public java.lang.String java.lang.String.toString()
public char java.lang.String.charAt(int)
private static void java.lang.String.checkBounds(byte[],int,int)
public int java.lang.String.codePointAt(int)
public int java.lang.String.codePointBefore(int)
public int java.lang.String.codePointCount(int,int)
public int java.lang.String.compareToIgnoreCase(java.lang.String)
public java.lang.String java.lang.String.concat(java.lang.String)
public boolean java.lang.String.contains(java.lang.CharSequence)
public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
public boolean java.lang.String.contentEquals(java.lang.CharSequence)
public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
public static java.lang.String java.lang.String.copyValueOf(char[])
public boolean java.lang.String.endsWith(java.lang.String)
public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
public static transient java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
public static transient java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
public byte[] java.lang.String.getBytes()
public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
public void java.lang.String.getBytes(int,int,byte[],int)
void java.lang.String.getChars(char[],int)
public void java.lang.String.getChars(int,int,char[],int)
public native java.lang.String java.lang.String.intern()
static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int)
public int java.lang.String.lastIndexOf(int)
public int java.lang.String.lastIndexOf(int,int)
public int java.lang.String.lastIndexOf(java.lang.String,int)
public int java.lang.String.lastIndexOf(java.lang.String)
public int java.lang.String.length()
public boolean java.lang.String.matches(java.lang.String)
public int java.lang.String.offsetByCodePoints(int,int)
public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
public java.lang.String java.lang.String.replace(char,char)
public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String,int)
public java.lang.String[] java.lang.String.split(java.lang.String)
public boolean java.lang.String.startsWith(java.lang.String)
public boolean java.lang.String.startsWith(java.lang.String,int)
public java.lang.CharSequence java.lang.String.subSequence(int,int)
public java.lang.String java.lang.String.substring(int)
public java.lang.String java.lang.String.substring(int,int)
public char[] java.lang.String.toCharArray()
public java.lang.String java.lang.String.toLowerCase()
public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
public java.lang.String java.lang.String.toUpperCase()
public java.lang.String java.lang.String.trim()
public static java.lang.String java.lang.String.valueOf(char[])
public static java.lang.String java.lang.String.valueOf(char)
public static java.lang.String java.lang.String.valueOf(int)
public static java.lang.String java.lang.String.valueOf(long)
public static java.lang.String java.lang.String.valueOf(float)
public static java.lang.String java.lang.String.valueOf(double)
public static java.lang.String java.lang.String.valueOf(java.lang.Object)
public static java.lang.String java.lang.String.valueOf(boolean)
public static java.lang.String java.lang.String.valueOf(char[],int,int)

 

示例代码二、实现对象的拷贝

java 代码
  1. package com.test.reflect;   
  2.   
  3. import java.lang.reflect.Field;   
  4. import java.lang.reflect.Method;   
  5.   
  6. /**  
  7.  * 实现对象的拷贝  
  8.  * @author yahaitt  
  9.  *  
  10.  */  
  11. public class ReflectCopyTest {   
  12.   
  13.     public Object copy(Object object) throws Exception   
  14.     {   
  15.         //获得对象的类型   
  16.         Class clazz_old = object.getClass();   
  17.            
  18.         //通过默认构造方法创建一个新的对象   
  19.         //1、需要注意的是getConstructor(new Class[]{})中的参数的个数必须和newInstance(new Object[]{})中的参数是一致的   
  20.         //2、通过class类的newInstance生成新对象只能通过不带参数的构造方法,如: Object o = clazz_old.newInstance();,如果clazz_old对应的类没有默认的不带参数的构造方法,则这里就会抛错。   
  21.         //3、通过Constructor的newInstance生成新对象可以通过带各种参数的构造方法,但是必须对应的类要存在这些构造方法,如果一个都没有,它并不会去调用默认的不带参数的构造方法,如果要去调用不带参数的构造方法,一定要在类里显式定义   
  22.         Object object_new = clazz_old.getConstructor(new Class[]{}).newInstance(new Object[]{});   
  23.            
  24.         //获得对象的所有属性   
  25.         Field[] fields = clazz_old.getDeclaredFields();   
  26.         for(Field field : fields)   
  27.         {   
  28.             String fieldName = field.getName();   
  29.             String firstLatter = fieldName.substring(0,1);   
  30.                
  31.             //获得和属性对应的getXXX()方法的名字   
  32.             String getMethodStr = "get" + firstLatter.toUpperCase() + fieldName.substring(1);   
  33.             //获得和属性对应的setXXX()方法的名字   
  34.             String setMethodStr = "set" + firstLatter.toUpperCase() + fieldName.substring(1);   
  35.                
  36.             //获得和属性对应的getXXX()方法   
  37.             Method getMethod = clazz_old.getMethod(getMethodStr, new Class[]{});   
  38.             //获得和属性对应的setXXX()方法   
  39.             Method setMethod = clazz_old.getMethod(setMethodStr, field.getType());   
  40.                
  41.             //调用原对象的getXXX()方法   
  42.             Object value = getMethod.invoke(object, new Object[]{});   
  43.             //调用拷贝对象的setXXX()方法   
  44.             setMethod.invoke(object_new, value);   
  45.         }   
  46.            
  47.         return object_new;   
  48.            
  49.     }   
  50.        
  51.     public static void main(String[] args) throws Exception {   
  52.            
  53.         ReflectCopyTest test = new ReflectCopyTest();   
  54.         Custom custom = new Custom();   
  55.         custom.setId(1);   
  56.         custom.setName("yahaitt");   
  57.         custom.setAge(20);   
  58.         Custom copy = (Custom) test.copy(custom);   
  59.         System.out.println(copy.getId());   
  60.         System.out.println(copy.getName());   
  61.         System.out.println(copy.getAge());   
  62.     }   
  63.   
  64. }   
  65.   
  66. class Custom   
  67. {   
  68.     private int id;   
  69.     private String name;   
  70.     private int age;   
  71.        
  72.     public Custom()   
  73.     {   
  74.            
  75.     }   
  76.        
  77.     public int getId() {   
  78.         return id;   
  79.     }   
  80.     public void setId(int id) {   
  81.         this.id = id;   
  82.     }   
  83.     public String getName() {   
  84.         return name;   
  85.     }   
  86.     public void setName(String name) {   
  87.         this.name = name;   
  88.     }   
  89.     public int getAge() {   
  90.         return age;   
  91.     }   
  92.     public void setAge(int age) {   
  93.         this.age = age;   
  94.     }   
  95.        
  96.        
  97. }   

输出结果是:

1
yahaitt
20

示例代码三、invoke的应用:

java 代码
  1. package com.test.reflect;   
  2.   
  3. import java.lang.reflect.Method;   
  4.   
  5. public class InvokeTest {   
  6.        
  7.     public int add(int a, int b)   
  8.     {   
  9.         return a + b;   
  10.     }   
  11.        
  12.     public String echo(String msg)   
  13.     {   
  14.         return "echo:" + msg;   
  15.     }   
  16.        
  17.     public static void main(String[] args) throws Exception {   
  18.            
  19.         Class<?> clazz = InvokeTest.class;   
  20.         Object test = clazz.newInstance();   
  21.            
  22.         Method addMethod =clazz.getMethod("add"new Class[]{int.classint.class});   
  23.         Method echoMethod = clazz.getMethod("echo"new Class[]{String.class});   
  24.            
  25.         // 调用InvokeTester对象的add()方法   
  26.         Object addValue = addMethod.invoke(test, new Object[]{new Integer(200), new Integer(100)});   
  27.         System.out.println((Integer)addValue);   
  28.            
  29.         // 调用InvokeTester对象的echo()方法   
  30.         Object echoValue = echoMethod.invoke(test, new Object[]{new String("hello")});   
  31.         System.out.println((String)echoValue);   
  32.            
  33.     }   
  34.   
  35. }   

 

输出结果是:

300
echo:hello

对示例三的说明:

1、add()方法的两个参数为int 类型,获得表示add()方法的Method对象的代码如下:
Method addMethod=clazz.getMethod("add",new Class[]{int.class,int.class});
Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回

2、在本例中,尽管InvokeTest 类的add()方法的两个参数以及返回值都是int类型,调用add Method 对象的invoke()方法时,只能传递Integer 类型的参数,并且invoke()方法的返回类型也是Integer 类型,Integer 类是int 基本类型的包装类:

Object result=addMethod.invoke(test,
new Object[]{new Integer(100),new Integer(200)});
System.out.println((Integer)result); //result 为Integer类型

分享到:
评论

相关推荐

    Java语言反射机制原理探析.pdf

    在Java语言中,反射机制是通过JVM(Java虚拟机)逆向执行的过程来实现的。具体来说,反射机制允许在运行时动态创建类的实例,动态调用类的方法,以及访问和设置类的属性等。本文将深入探讨Java反射机制的原理及其在...

    Java语言反射机制原理探析.zip

    Java语言的反射机制是其强大的特性之一,它允许在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这一机制对于理解和利用Java的灵活性至关重要,尤其在元编程、框架设计、插件系统以及...

    java面试题--反射机制

    这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射机制的核心概念、基本原理及其应用场景。 #### 二、Java反射机制简介 Java反射机制允许...

    Java反射机制 Java反射机制

    Java反射机制是Java语言的一个重要特性,它允许程序在运行时获取类的信息并操作对象。Java反射机制的主要作用包括:获取类的所有属性和方法、构造动态实例、调用类的方法等。通过反射,程序可以动态地创建对象和调用...

    java的反射机制及其实际应用

    Java作为一种强大的编程语言,提供了许多高级特性,其中反射机制尤为突出。通过反射,开发者可以在运行时动态地获取类的信息并操纵类的行为,从而实现更加灵活和扩展性强的程序设计。 #### 二、Java中的类反射 ###...

    JAVA反射机制应用

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

    Java中的反射机制

    此外,LEAD/LEAD++、OpenC++、MetaXa和OpenJava等编程语言都是基于反射机制构建的。 反射不仅限于编程语言领域,近年来也被广泛应用于视窗系统、操作系统以及文件系统中。尽管“反射”一词在计算机科学中有着全新的...

    Java 1.5 反射机制

    Java 1.5引入的反射机制是其动态性的一个重要体现,它允许程序在运行时检查和操作类、接口、对象及其方法。反射为开发者提供了强大的能力,可以在不知道具体类名的情况下实例化对象,调用方法,访问字段,以及处理...

    Java语言的反射机制.pdf

    Java语言的反射机制 Java语言的反射机制是Java语言中一个非常重要的机制,它允许程序在运行时加载、探知、使用编译期间完全未知的class。这种“看透class”的能力被称为introspection。反射机制的概念是由Smith在...

    反射实例-JAVA反射机制

    这是Java语言特有的功能,使得Java程序比其他语言(如C、C++)更加灵活。 ##### 2.1 Reflection的工作机制示例 下面通过一个简单的示例来展示Java反射机制的工作流程: ```java import java.lang.reflect.*; ...

    候捷谈Java反射机制

    Java反射机制是Java编程语言...总之,Java反射机制是Java语言中一个强大的工具,它增强了Java的灵活性,允许开发者在运行时探索和操作类的内部结构。尽管反射带来了诸多便利,但也需要合理使用,以平衡灵活性和稳定性。

    java反射机制详解

    反射机制是Java编程语言的一个核心特性,它允许程序在运行时动态地获取类的信息,并且能够动态地创建对象和调用对象的方法。简单来说,反射机制使得Java程序可以自我检查、自我调整。 在Java中,所有的类型都是`...

    Java反射机制

    Java反射机制是Java语言的一种重要特性,使得Java成为了一种动态性很强的语言。通过反射,可以在程序运行时获取类的信息,包括类名、父类、接口、字段、方法等,并能够调用类的任意方法。这种能力对于构建高度灵活和...

    Java反射机制总结

    ### Java反射机制总结 ...总之,Java反射机制是Java语言的一个重要特性,它提供了在运行时动态获取类信息和操作类结构的能力。合理使用反射可以提高程序的灵活性和扩展性,但在使用时也需要考虑到其潜在的问题和限制。

Global site tag (gtag.js) - Google Analytics