`

java反射技术及代理模式(二)

阅读更多
在例程InvokeTester类的main()方法中,运用反射机制调用一个InvokeTester对象的add()和echo()方法

InvokeTester.java

import java.lang.reflect.Method;

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();

        // Object invokeTester = classType.getConstructor(new
        // Class[]{}).newInstance(new Object[]{});

        // 调用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);
    }
}



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

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

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


*************************************
java.lang.Array 类提供了动态创建和访问数组元素的各种静态方法。例程
ArrayTester1 类的main()方法创建了一个长度为10 的字符串数组,接着把索引位置为5 的元素设为“hello”,然后再读取索引位置为5 的元素的值

ArrayTester1.java

import java.lang.reflect.Array;

public class ArrayTester1
{
    public static void main(String args[]) throws Exception
    {
        Class<?> classType = Class.forName("java.lang.String");
        // 创建一个长度为10的字符串数组
        Object array = Array.newInstance(classType, 10);
        // 把索引位置为5的元素设为"hello"
        Array.set(array, 5, "hello");
        // 获得索引位置为5的元素的值
        String s = (String) Array.get(array, 5);
        System.out.println(s);
    }
}



例程ArrayTester2 类的main()方法创建了一个 5 x 10 x 15 的整型数组,并把索引位置为[3][5][10] 的元素的值为设37

ArrayTester2.java

import java.lang.reflect.Array;

public class ArrayTester2
{
	public static void main(String args[])
	{
		//定义一个一维数组
		int[] dims = new int[] { 5, 10, 15 };
		//定义一个Array对象,三维数组,
		//Array.newInstance(Integer.TYPE, dims)第二个参数为数组,数组的长度就是维数
		Object array = Array.newInstance(Integer.TYPE, dims);
		//java中多维数组,就是数组的数组,得到一个二维数组
		Object arrayObj = Array.get(array, 3);
		Class<?> cls = arrayObj.getClass().getComponentType();
		System.out.println(cls);
		//得到一个一维数组
		arrayObj = Array.get(arrayObj, 5);
		//给数组的第10个元素设置值
		Array.setInt(arrayObj, 10, 37);
		
		int arrayCast[][][] = (int[][][]) array;
		System.out.println(arrayCast[3][5][10]);
	}
}



******************************************************

“Class”   class

众所周知Java有个Object class,是所有Java classes的继承根源,其内声明了数个应该在所有Java class中被改写的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class object。

Class class十分特殊。它和一般classes一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types
(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class object。如果您想借由“修改Java标准库源码”来观察Class object的实际生成时机(例如在Class的constructor内添加一个println()),不能够!因为Class并没有public constructor

Class是Reflection起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs


“Class” object的取得途径

===========================================================
Class object 诞生管道           =                   示例
===========================================================
运用getClass()
注:每个class都有此函数           =           String str = "abc";
                                          Class c1 = str.getClass();
===========================================================
运用Class.getSuperclass()     =         Button b1 = new Button();
                                       Class c1 = b.getClass();
                                       Class c2 = c1.getSuperclass();
===========================================================
运用static method             =       Class c1 = Class.forName("java.String");
Class.forName()
(最常被使用)
&&&&&&&&&&&&&&&
见上传文件吧,&&&
&&&&&&&&&&&&&&&

运行时生成instances

欲生成对象实体,在Reflection 动态机制中有两种作法,一个针对“无自变量ctor”,一个针对“带参数ctor”。如果欲调用的是“带参数ctor“就比较麻烦些,不再调用Class的newInstance(),而是调用Constructor 的newInstance()。首先准备一个Class[]做为ctor的参数类型(本例指定
为一个double和一个int),然后以此为自变量调用getConstructor(),获得一个专属ctor。接下来再准备一个Object[] 做为ctor实参值(本例指定3.14159和125),调用上述专属ctor的newInstance()。

Class c = Class.forName("DynTest");
Object obj = null;
obj = c.newInstance();//不带自变量
System.out.println(obj);



动态生成“Class object 所对应之class”的对象实体;无自变量。


Class c = Class.forName("DynTest");
Class[] pTypes = new Class[]{double.class,int.class};
Constructor ctor = c.getConstructor(pTypes);
Object obj = null;
Object[] arg = new Object[]{3.124,23};
obj = ctor.newInstance(arg);
System.out.println(obj);



运行时调用methods


这个动作和上述调用“带参数之ctor”相当类似。首先准备一个Class[]做为参数类型(本例指定其中一个是String,另一个是Hashtable),然后以此为自变量调用getMethod(),获得特定的Method object。接下来准备一个Object[]放置自变量,然后调用上述所得之特定Method object的invoke()。
为什么获得Method object时不需指定回返类型?

因为method overloading机制要求signature必须唯一,而回返类型并非signature的一个成份。换句话说,只要指定了method名称和参数列,就一定指出了一个独一无二的method。

Class c = Class.forName("java.lang.String");
Method method = c.getMethod("method name",方法参数类型);


**************************
与先前两个动作相比,“变更field内容”轻松多了,因为它不需要参数和自变量。首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set(),

import java.lang.reflect.Field;

public class Test {
	public double d;
	public static void main(String[] args) throws Exception {
		Class<?> c = Class.forName("Test");
		//利用字段名得到一个Field对象
		Field f = c.getField("d");
		Test obj = new Test();
		//利用Field类的get方法得到某个对象的此字段
		System.out.println("d= "+(Double)f.get(obj));
		f.set(obj, 12.36);
		System.out.println("d= "+obj.d);
	}
}




















分享到:
评论

相关推荐

    Java反射与设计模式

    本文详尽地论述了Java反射,工厂模式,动态代理模式

    Java的反射与代理实现IOC模式

    #### 二、Java反射机制的演示实例 接下来,我们通过一个简单的示例来展示如何使用Java反射API。 ```java package org.amigo.reflection; import java.awt.Button; import java.lang.reflect.Method; import java....

    JAVA设计模式(代理模式)

    **Java设计模式——代理模式详解** 代理模式是软件设计模式中的一个重要组成部分,它在Java编程中扮演着举足轻重的角色。代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象可以控制对原...

    JAVA的反射机制与动态代理

    Java的反射机制与动态代理是Java编程中两个非常重要的高级特性,它们在许多实际场景中发挥着关键作用,如框架开发、插件系统、元数据处理等。下面将详细讲解这两个概念及其应用。 首先,Java的反射机制允许我们在...

    JAVA反射与代理

    代理模式是一种设计模式,用于在目标对象前添加一层代理,以控制对目标对象的访问。在Java中,有两种代理方式:静态代理和动态代理。 静态代理是通过定义一个代理类来实现的,代理类和目标类实现了相同的接口,代理...

    Java代理模式Java动态代理

    Java动态代理是基于Java反射机制的一种实现方式,它允许我们在运行时动态地创建一个实现了某些接口的新类。Java动态代理主要用于创建代理对象,这些代理对象可以实现在特定时刻的行为增强。 **1. Java动态代理类的...

    利用Java的反射与代理实现IOC模式

    在这个主题中,我们将深入探讨Java反射和动态代理如何帮助我们实现IOC。 首先,让我们理解Java反射。反射允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。在IOC中,反射用于在...

    java 反射技术 设计模式 spring security 安全管理手册

    Java反射技术是Java编程语言中一个强大的特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。通过反射,我们可以动态地获取类的信息(如类名、属性、方法等)并进行调用,甚至在不知道具体...

    Java反射和动态代理实例

    几个Java反射和动态代理的小例子。可以学习如何通过Java的反射机制实例化对象、调用对象的方法、操作对象的私有成员变量、改变数组中的某项的值、改变数组大小等;可以学习Java的动态代理模式、学习Java工厂模式以及...

    java中的三种代理模式

    JDK动态代理基于Java反射API,可以在运行时动态地生成代理类和实例。它需要目标对象实现至少一个接口,然后通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来创建代理对象。...

    Java反射及动态代理

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,甚至能够在运行时创建和操作类的对象。反射机制是通过`java.lang.reflect`包中的类和接口实现的,它为我们提供了对程序...

    Java反射机制和动态代理

    主要讲述Java反射机制与设计模式之一:代理模式的原理与应用;同时详细讲述了Java对代理模式的支持以及Java中动态代理的原理,应用与实践。

    java反射及动态代理

    ### Java反射机制详解 #### 一、Type及其子类 `Type`是Java编程语言中所有类型的公共高级接口。它包括原始类型、参数化类型、数组类型、类型变量和基本类型。 - **原始类型**:如`int`, `double`等。 - **参数化...

    JAVA 反射详解PPT

    代理模式在Java中主要有两种形式:静态代理和动态代理。静态代理是在编译时就已经确定了代理类,而动态代理则是在运行时通过反射机制创建代理对象。动态代理的灵活性更高,因为它不需要为每个接口编写单独的代理类,...

    java反射.pdf

    #### 七、动态代理模式 1. **动态代理简介**: - 动态代理是基于反射的一种技术,用于创建一个代理类来代理其他类的方法调用。 - 动态代理可以避免为每个业务层实现类编写单独的代理类,从而减少代码量。 - 它...

    JAVA 反射机制与动态代理ppt

    总的来说,Java反射机制和动态代理是Java平台强大而灵活的特性,它们使得Java程序能够在运行时具有更高的灵活性和可扩展性。然而,使用反射也可能带来性能开销和安全风险,因此在实际应用中需要权衡利弊,合理使用。

    Java反射机制与动态代理

    代理模式通常用于实现AOP(面向切面编程),比如日志记录、性能监控、事务管理等。当需要在调用目标方法前后添加额外操作时,动态代理就显得非常方便。通过实现`InvocationHandler`,我们可以控制代理对象的行为,当...

    java 反射的使用

    以下是对Java反射使用及相关知识点的详细阐述: 1. **获取Class对象** - `Class.forName(String className)`: 通过全限定类名获取Class对象。 - `object.getClass()`: 对象的`getClass()`方法返回该对象的Class...

    java反射机制PPT

    代理模式是设计模式中的一种,主要用来在不修改原有对象的情况下,为对象添加额外功能。Java中,动态代理(Dynamic Proxy)是通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现的,...

Global site tag (gtag.js) - Google Analytics