JAVA Reflection(反射机制)

Java 反射机制

  反射机制简介

  反射机制应用示例

  简单的Ioc实现

  代理模式

  Java动态代理

  简单的Aop实现

  “程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,PythonRuby是动态语言,C++,Java,C#不是动态语言。

  尽管在这样得定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关的机制:反射机制 (Reflection)。

  什么是反射?

  反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或者行为的一种能力。

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

  JAVA反射机制(Reflection)

  动态获取类的信息,以及动态调用对象的方法的功能。

  主要提供了以下功能:

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

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

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

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

  生成动态代理。

  JAVA反射机制包

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

  Class 类:代表一个类。

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

  Method 类:代表类的方法。

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

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

  java.lang.Class

  static Class forName(String className)

  返回描述类名为className的Class对象

  Object newInstance()

  返回一个类的一个新实例

  Field[] getFields()

  返回包含Field对象的数组,这些对象记录了这个类或者其超类的公共域

  Field[] getDeclaredField()

  返回包含Field对象的数组,这些对象记录了这个类的全部域

  Method[] getMethods()                             返回这个类或者其超类所有的公有方法

  Method[] getDeclareMethods()                 返回这个类或者接口的所有方法,不包括超类继承的方法

  Constructor[] getConstructors()                返回所有包含了Class对象所描述类的公有构造器

  Constructor[] getDeclaredConstructors()  返回包含了Class对象所描述的类的所有构造器

 Java.lang.reflect.Constructor

  Class[] getParameterTypes()

  返回一个用于描述参数类型的Class对象数组

  getReturnType()

  返回一个用于描述返回类型的Class对象

  int getModifiers()

  返回一个用于描述方法抛出的异常类型的Class对象数组

  Class getDeclaringClass()

  返回一个用于描述类中定义的构造器、方法或域的Class对象

  通过反射实例化参数

  平常实例化对象通常使用new关键字。但是使用new关键字实例化的对象具有强耦合性。New对象无法胜任未知对象的实例化,这时候只能通过反射动态生成。例如Spring的DI。

  实例化无参构造函数的对象

  Class.newInstance()

  Class.getConstructor(new Class[]{}).newInstance(new Object[]{})

  实例化带参构造函数的对象

  Clazz.getConstructor(Class<?> ...ParameterType).newInstance(Object ...initargs)

  反射机制举例


import java.lang.reflect.*;

public class DumpMethods {

public static void main(String args[]) throws Exception{

//加载并初始化命令行参数指定的类

Class classType = Class.forName(args[0]);

//获得类的所有方法

Method methods[] = classType.getDeclaredMethods();

for(int i = 0; i < methods.length; i++)

System.out.println(methods[i].toString());

}

}


输入:java DumpMethods java.util.Stack

public synchronized java.lang.Object java.util.Stack.pop()

public java.lang.Object java.util.Stack.push(java.lang.Object)

public boolean java.util.Stack.empty()

public synchronized java.lang.Object java.util.Stack.peek()

public synchronized int java.util.Stack.search(java.lang.Object)

  运用反射机制调用方法

  getMethod和invoke方法的时序图

 获取反射对象

import java.lang.reflect.*;

public class ReflectTester {

public Object  copy(Object object) throws Exception{

//获得对象的类型

Class classType=object.getClass();

System.out.println("Class:"+classType.getName());

//通过默认构造方法创建一个新的对象

Object  objectCopy=classType.getConstructor(new Class[]{}).

newInstance(new Object[]{});

//获得对象的所有属性

Field fields[]=classType.getDeclaredFields();

for(int i=0; i<fields.length;i++){

Field field=fields[i];

String fieldName=field.getName();

String firstLetter=fieldName.substring(0,1).toUpperCase();

//获得和属性对应的 getXXX()方法的名字

String getMethodName="get"+firstLetter+fieldName.substring(1);

//获得和属性对应的 setXXX()方法的名字

String setMethodName="set"+firstLetter+fieldName.substring(1);

//获得和属性对应的 getXXX()方法

Method getMethod=classType.getMethod(getMethodName,new Class[]{});

//获得和属性对应的 setXXX()方法

Method setMethod=classType.getMethod(setMethodName,new Class[]{field.getType()});

//调用原对象的 getXXX()方法

Object value=getMethod.invoke(object,new Object[]{});

System.out.println(fieldName+":"+value);

//调用复制对象的 setXXX()方法

setMethod.invoke(objectCopy,new Object[]{value});

}

return objectCopy;

}

public static void main(String[] args) throws Exception{

Customer customer=new Customer("Tom",21);

customer.setId(new Long(1));

Customer customerCopy=(Customer)new ReflectTester().copy(customer);

System.out.println("Copy information:"+customerCopy.getName()+

“ "+  customerCopy.getAge());

}

}

  运用反射机制调用方法

class Customer{

//Customer 类是一个 JavaBean

private Long id;

private String name;

private int age;

public Customer(){}

public Customer(String name,int age){

this.name=name;

this.age=age;

}

public Long getId(){return id;}

public void setId(Long id){this.id=id;}

public String getName(){return name;}

public void setName(String name){this.name=name;}

public int getAge(){return age;}

public void setAge(int age){this.age=age;}

}

import java.lang.reflect.*;

public class InvokeTester {

public int add(int param1,int param2){  return param1+param2;   }

public String echo(String msg){   return "echo:"+msg; }

public static void main(String[] args) throws Exception{

Class classType=InvokeTester.class;

Object invokeTester=classType.newInstance();

//调用 InvokeTester 对象的 add()方法

Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});

Object result=addMethod.invoke(invokeTester,

new Object[]{new Integer(100),new Integer(200)});

System.out.println((Integer)result);

//调用 InvokeTester 对象的 echo()方法

Method echoMethod=classType.getMethod("echo",new Class[]{String.class});

result=echoMethod.invoke(invokeTester,new Object[]{"Hello"});

System.out.println((String)result);

}

}

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-07-31 06:31:24

JAVA Reflection(反射机制)的相关文章

java的反射机制的问题

问题描述 java的反射机制的问题 111111111111111111111111111111111111111111111 解决方案 反射机制,好像是这样子,在public类里我创建了一个接口,可惜,我都不知道我什么时候用它,所以我就不初始化它了,突然有一天,我要初始化他一次,于是我就用反射机制来给它初始化一下.不知道对不对? 解决方案二: java反射机制及性能优化问题Java进阶(六)Java反射机制可恶问题NoSuchFieldExceptionJAVA中的反射机制 解决方案三: 这个

Java的反射机制---动态调用对象的简单方法_java

唉!我还真是在面试中学习新东东啊,一个公司刚刚给了个测试,不过我很奇怪的是为什么web developer的职位居然考java的反射机制题,不过学习研究一下反射机制对我来说是件好事啦! 先说说什么是java反射机制吧,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这 种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.主要功能:在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对 象:在运行时判断任意一个

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

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

Java通过反射机制动态设置对象属性值的方法_java

/** * MethodName: getReflection<br> * Description:解析respXML 在通过反射设置对象属性值 * User: liqijing * Date:2015-7-19下午12:42:55 * @param clzzName * @param respXML * @return * @throws ClassNotFoundException * @throws DocumentException * @throws IllegalArgumentE

PHP中的reflection反射机制测试例子_php实例

Java类反射应用得非常广泛几乎是所有框架的最核心部分,PHP程序员似乎从不关心反射.尝试着用java的思想去理解php的反射,跟java基本上基本一致.参考了php手册:http://www.php.net/manual/zh/book.reflection.php. ReflectTest.php: <?php   class ReflectTest {       /**      * 用户ID      */     private $userId;       /**      * 用

kettle job如何利用java的反射机制获取执行的sql语句

kettle job中的JavaScript如何获取同一个job中SQL步骤的执行语句并让执行语句记录在日志中呢?首先写日志需要用到job中JavaScript写日志的方法,其次是利用java反射机制获取执行的sql. 如: var sqlObj = getJobStep("SQL"); var sql = sqlObj.environmentSubstitute(sqlObj.getSQL()); var logWriter = org.pentaho.di.core.logging

用java的反射机制,能不能调用到单例模式类中的方法(非静态)?

问题描述 1.HelloWorld 类:public class HelloWorld { private static HelloWorld instance = null; private HelloWorld() { } public static HelloWorld getInstance() { if (instance == null) { instance = new HelloWorld(); } return instance; } public void sayHello(

利用Java Reflection(反射)原理,在hibernate里面实现对单表、视图的动态组合查询

动态|视图|组合查询     Reflection 是 Java 程序开发语言的特征之一,它允许运行中的程序对自身进行访问,并能直接操作程序的内部属性.     Hibernate是一个面向Java环境的对象/关系数据库映射工具,基本上,每个表或者视图在hibernate里面都可以对应一个类,在此处,我们通过充分的利用这个类,来实现动态组合查询. 首先我们一起来看看这个函数的源代码:     /**     * 组合查询     * @param object 包含查询条件的对象     * @

实例介绍PHP的Reflection反射机制_php实例

PHP5添加了一项新的功能:Reflection.这个功能使得程序员可以reverse-engineer class, interface,function,method and extension.通过PHP代码,就可以得到某object的所有信息,并且可以和它交互. 假设有一个类Person: 复制代码 代码如下: class Person {   /**      * For the sake of demonstration, we"re setting this private    

java中反射机制通过字节码文件对象获取字段和函数的方法

pclass = Class.forName("get_class_method.Person"); //Field ageField = pclass.getField("age");//因为age成员变量是私有的,所以会产生NoSuchFieldException异常 Field ageField = pclass.getDeclaredField("age");//获得该对象反映此 Class 对象所表示的类或接口的指定已声明字段 Obje