基本概念

  在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?

  答案是肯定的。

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

  

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

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

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

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

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

  Reflection是Java被视为动态(或准动态)语言的一个关键性质。

  这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息。

  包括其modifiers(诸如public、static等)、 superclass(例如Object)、实现了的 interfaces (例如Serializable)、也包括其fields和methods的所有信息,并可于运行时改变fields内容或调用methods。

动态语言

  动态语言的定义“程序运行时,允许改变程序结构或者变量类型,这种语言称为动态语言”。

  从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。

  尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是:反射、映像、倒影,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。

  换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

  这种“看透”class的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflectionintrospection是常被并提的两个术语。

Java Reflection API简介

  在JDK中,主要由以下类来实现Java反射机制,这些类(除了第一个)都位于java.lang.reflect包中

  Class类:代表一个类,位于java.lang包下。

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

  Method类:代表类的方法。

  Constructor类:代表类的构造方法。

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

Class对象

  要想使用反射,首先需要获得待操作的类所对应的Class对象。

  Java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class对象。

  这个Class对象是由JVM生成的,通过它能够获悉整个类的结构。

常用的获取Class对象的3种方式:

  1.使用Class类的静态方法。例如:  

Class.forName("java.lang.String");

  2.使用类的.class语法。如:

String.class;

  3.使用对象的getClass()方法。如:

String str = "aa";
Class<?> classType1 = str.getClass();

  getClass()方法定义在Object类中,不是静态方法,需要通过对象来调用,并且它声明为final,表明不能被子类所覆写。

  直接print所获得的Class对象classType会输出:

    class 完整类名

  如果调用该Class对象的getName()方法,则输出完整类名,不加class。

例程1:获取方法

  例程ReflexTest 类演示了Reflection API的基本作用,它读取命令行参数指定的类名,然后打印这个类所具有的方法信息。 

package com.reflex;

import java.lang.reflect.Field;
import java.lang.reflect.Method; public class ReflexTest { public static void main(String[] args) {
try {
Class c = Class.forName("java.lang.Integer");
Field[] fs = c.getDeclaredFields(); for(Field f:fs){
System.out.println(f);
}
System.out.println("==================================================");
Method[] methods = c.getDeclaredMethods();
for(Method method:methods){
System.out.println(method);
} } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

结果:

public static final int java.lang.Integer.MIN_VALUE
public static final int java.lang.Integer.MAX_VALUE
public static final java.lang.Class java.lang.Integer.TYPE
static final char[] java.lang.Integer.digits
static final char[] java.lang.Integer.DigitTens
static final char[] java.lang.Integer.DigitOnes
static final int[] java.lang.Integer.sizeTable
private final int java.lang.Integer.value
public static final int java.lang.Integer.SIZE
private static final long java.lang.Integer.serialVersionUID
static final boolean java.lang.Integer.$assertionsDisabled
==================================================
public int java.lang.Integer.hashCode()
public boolean java.lang.Integer.equals(java.lang.Object)
public static java.lang.String java.lang.Integer.toString(int,int)
public java.lang.String java.lang.Integer.toString()
public static java.lang.String java.lang.Integer.toString(int)
public static java.lang.String java.lang.Integer.toHexString(int)
public static int java.lang.Integer.compare(int,int)
public int java.lang.Integer.compareTo(java.lang.Object)
public int java.lang.Integer.compareTo(java.lang.Integer)
public static java.lang.Integer java.lang.Integer.decode(java.lang.String) throws java.lang.NumberFormatException
static void java.lang.Integer.getChars(int,int,char[])
public static java.lang.Integer java.lang.Integer.valueOf(int)
public static java.lang.Integer java.lang.Integer.valueOf(java.lang.String,int) throws java.lang.NumberFormatException
public static java.lang.Integer java.lang.Integer.valueOf(java.lang.String) throws java.lang.NumberFormatException
public long java.lang.Integer.longValue()
public int java.lang.Integer.intValue()
public static int java.lang.Integer.reverse(int)
static int java.lang.Integer.stringSize(int)
public static int java.lang.Integer.reverseBytes(int)
public byte java.lang.Integer.byteValue()
public double java.lang.Integer.doubleValue()
public float java.lang.Integer.floatValue()
public short java.lang.Integer.shortValue()
public static int java.lang.Integer.parseInt(java.lang.String) throws java.lang.NumberFormatException
public static int java.lang.Integer.parseInt(java.lang.String,int) throws java.lang.NumberFormatException
public static int java.lang.Integer.bitCount(int)
public static java.lang.Integer java.lang.Integer.getInteger(java.lang.String,int)
public static java.lang.Integer java.lang.Integer.getInteger(java.lang.String)
public static java.lang.Integer java.lang.Integer.getInteger(java.lang.String,java.lang.Integer)
public static int java.lang.Integer.highestOneBit(int)
public static int java.lang.Integer.lowestOneBit(int)
public static int java.lang.Integer.numberOfLeadingZeros(int)
public static int java.lang.Integer.numberOfTrailingZeros(int)
public static int java.lang.Integer.rotateLeft(int,int)
public static int java.lang.Integer.rotateRight(int,int)
public static int java.lang.Integer.signum(int)
public static java.lang.String java.lang.Integer.toBinaryString(int)
public static java.lang.String java.lang.Integer.toOctalString(int)
private static java.lang.String java.lang.Integer.toUnsignedString(int,int)

例程2:通过反射调用方法

  通过反射调用方法。详情见代码及注释:

package com.reflex;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class InvokeTester { public int add(int param1, int param2) {
return param1 + param2;
} public String echo(String message) {
return "Hello: " + message;
} public static void main(String[] args)
throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
// 以前的常规执行手段
InvokeTester tester = new InvokeTester();
System.out.println(tester.add(1, 2));
System.out.println(tester.echo("Tom"));
System.out.println("---------------------------"); // 通过反射的方式
// 第一步,获取Class对象
// 前面用的方法是:Class.forName()方法获取
// 这里用第二种方法,类名.class
Class<?> classType = InvokeTester.class;
Object invokeTester = classType.newInstance();
System.out.println(invokeTester instanceof InvokeTester);// 输出true // 通过反射调用方法
// 首先需要获得与该方法对应的Method对象
// 第一个参数是方法名,第二个参数是这个方法所需要的参数的Class对象的数组
Method addMethd = classType.getMethod("add", new Class[] { int.class, int.class });
// 调用目标方法
Object addResult = addMethd.invoke(invokeTester,new Object[]{1,2});
System.out.println(addResult); //调用第二个echo方法
Method echoMethod = classType.getMethod("echo", new Class[] {String.class});
Object echoResult = echoMethod.invoke(invokeTester,new Object[]{"tom"});
System.out.println(echoResult);
}
}

生成对象

  若想通过类的不带参数的构造方法来生成对象,我们有两种方式:

  1.先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:

2.先获得Class对象,然后通过该对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成

  (其中Customer是一个自定义的类,有一个无参数的构造方法,也有带参数的构造方法):
    Class<?> classType = String.class;

     Object obj = classType.newInstance();
Class<?> classType = Customer.class;

    // 获得Constructor对象,此处获取第一个无参数的构造方法的
Constructor cons = classType.getConstructor(new Class[] {}); // 通过构造方法来生成一个对象
Object obj = cons.newInstance(new Object[] {});

若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:

  (Customer为一个自定义的类,有无参数的构造方法,也有一个带参数的构造方法,传入字符串和整型)

    Class<?> classType = Customer.class;

    Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class});

    Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});

11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇的更多相关文章

  1. 11 java 反射机制

    Java反射机制的适用场景及其利与弊: http://blog.csdn.net/zolalad/article/details/29370565 http://my.oschina.net/u/10 ...

  2. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  3. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  4. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  5. [转]java反射机制

    原文地址:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html 一.什么是反射机制         简单的来说,反射机制指的是程序在运 ...

  6. Java反射机制详解

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

  7. Java反射机制(Reflection)

    Java反射机制(Reflection) 一.反射机制是什么 Java反射机制是程序在运行过程中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种 ...

  8. JAVA反射机制学�

    JAVA反射机制:对于随意一个类,都可以知道这个类的全部属性和方法:对于随意一个对象,都可以调用它的随意一个方法和属性:这样的动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. J ...

  9. Java 反射机制浅析

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

随机推荐

  1. php---分组函数group_concat()

    group_concat()函数总结 group_concat(),手册上说明:该函数返回带有来自一个组的连接的非NULL值的字符串结果.比较抽象,难以理解. 通俗点理解,其实是这样的:group_c ...

  2. jQuery 复选框全选反选

    <script type="text/javascript"> $(function(){ //全选 $("#CheckedAll").click( ...

  3. JS:checkFrom对输入框和文本框的判断总结

    天看了老东家的一个专题页面,发现里边的checkFrome.js收集了很多对文本框的判断,非常有用收藏一下.其中包含了:1.页面截取字符串2.文本框最大长度限制3.判断必须是数字和字母的组合4.判断是 ...

  4. css实现三角箭头

    像下面的向右三角箭头,只有纯css不需要图片就可以实现了. width:0px;height:0px;border-width:0px 16px 20px 16px; border-style:sol ...

  5. JavaScript学习之对象

    JavaScript对象 一.对象简介 JavaScript 是面向对象的编程语言 (OOP).OOP 语言使我们有能力定义自己的对象和变量类型.注意:对象只是一种特殊的数据.对象拥有属性和方法. 1 ...

  6. JQuery 内容过滤选择器

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  7. Oracle一个实例配置多个监听

    要想给一个Oracle实例配置多个监听,首先要定义多个监听器,因为是多个监听,势必会有一些监听端口不是1521. 现在服务端的listener.ora文件中定义如下监听器: LISTENER = (D ...

  8. navicat 链接不上mysql

    1 查看 my.cnf 的配置bindhost 127.0.0.1 注释掉 2 grant all privileges on *.* to root@'%' identified by 'passw ...

  9. window操作技巧

    word中符号替换 1. 在网页复制内容时,下箭头用"^l"表示(字母L小写),回车用"^p"表示,可用替换命令全局替换(ctrl+f). 2. 添加底纹菜单在 ...

  10. [转载]CAD文件版本

    http://blog.sina.com.cn/s/blog_4c9fa4dd0101il1v.html 在工作中会遇到打开一张图纸时出现“图形文件无效”的提示,大部都是因为用低版本软件打开了高版本的 ...