//-------------------------------------

//类ArgumentHolder

//用于调用参数的封装,实现变长参数及

//不同类型参数的统一形式地传递

//成员变量:

// Class[] cl 参数类型数组

// Object[] args 参数对象数组

//方法:

// getArgumentClasses()返回参数类型数组

// getArguments() 返回参数对象数组

// setArgument() 在参数列表中增加项目

//

//---------------------------------------

public class ArgumentHolder {

protected Class[] cl;

protected Object[] args;

protected int argc;

ArgumentHolder() {

argc = 0;

cl = new Class[0];

args = new Object[0];

}

ArgumentHolder(int argc) {

this.argc = argc;

cl = new Class[argc];

args = new Object[argc];

}

public Class[] getArgumentClasses() {

return cl;

}

public Object[] getArguments() {

return args;

}

//以下16个setArgument

//函数实现简单数据类型boolean,byte,

// char,int,short,long,float,double的封装。

//为支持Invoker

//类dynaCall方法中getClass的调用,

//此处将简单数据类型

//转换为对应的对象,如boolean转换为Boolean

public int setArgument(boolean b) {

return this.setArgument(argc, new Boolean(b),

Boolean.TYPE);

}

public int setArgument(int argnum, boolean b) {

return this.setArgument(argnum, new Boolean(b),Boolean.TYPE);

}

public int setArgument(byte b) {

return this.setArgument(argc, new Byte(b),Byte.TYPE);

}

public int setArgument(int argnum, byte b) {

return this.setArgument(argnum, new Byte(b),Byte.TYPE);

}

public int setArgument(char c) {

return this.setArgument(argc, new Character(c),Character.TYPE);

}

public int setArgument(int argnum, char c) {

return this.setArgument(argnum, new Character(c),Character.TYPE);

}

public int setArgument(int i) {

return this.setArgument(argc, new Integer(i),Integer.TYPE);

}

public int setArgument(int argnum, int i) {

return this.setArgument(argnum, new Integer(i), Integer.TYPE);

}

public int setArgument(short s) {

return this.setArgument(argc, new Short(s),Short.TYPE);

}

public int setArgument(int argnum, short s) {

return this.setArgument(argnum, new Short(s),Short.TYPE);

}

public int setArgument(long l) {

return this.setArgument(argc, new Long(l),Long.TYPE);

}

public int setArgument(int argnum, long l) {

return this.setArgument(argnum, new Long(l),Long.TYPE);

}

public int setArgument(float f) {

return this.setArgument(argc, new Float(f),Float.TYPE);

}

public int setArgument(int argnum, float f) {

return this.setArgument(argnum, new Float(f),

Float.TYPE);

}

public int setArgument(double d) {

return this.setArgument(argc, new Double(d),Double.TYPE);

}

public int setArgument(int argnum, double d) {

return this.setArgument(argnum, new Double(d),Double.TYPE);

}

//以下2个setArgument函数实现对象的封装,

public int setArgument(Object obj) {

return this.setArgument(argc, obj,

obj.getClass());

}

public int setArgument(int argnum, Object obj) {

return this.setArgument(argnum, obj,

obj.getClass());

}

//以下setArgument函数具体实现以对象形式

//提供的参数封装。

//具体操作为:增加计数器argc的值、

//在cl和args中增加相应内容

public int setArgument(int argnum,Object obj, Class c) {

if (argnum >= args.length) {

argc = argnum + 1;

Class[] clExpanded = new Class[argc];

Object[] argsExpanded = new Object[argc];

System.arraycopy(cl, 0, clExpanded,

0, cl.length);

System.arraycopy(args, 0, argsExpanded,

0, args.length);

cl = clExpanded;

args = argsExpanded;

}

args[argnum] = obj;

cl[argnum] = c;

return argnum;

}

}

//

//---- 以 下 给 出 一 个 类Invoker 和ArgumentHolder 的 应 用 实 例。

//类DynaCallTest 应 用 类Invoker 和ArgumentHolder 实 现 以 下 功 能: 根 据 用 户 在 命 令 行 中 输 入 的 内 容, 动 态 地 确 定 所 调 用 方 法。 程 序 可 以 接 受 的 合 法 输 入 为:

//

//add 参数为两个整数,显示两个整数之和

//concat 参数为两个字符串,显示两个字符串连接之后的值

//help 无参数,显示可以接受的命令列表

//minmax 参数为三个整数,显示三个参数的最大之和最小值

//quit 无参数,结束运行

//rand 无参数,显示一个随机值

//

//程序清单如下:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.lang.reflect.InvocationTargetException;

import java.util.Random;

import java.util.StringTokenizer;

public class DynaCallTest {

Random rand;

BufferedReader consoleIn;

//建构函数,初始化

DynaCallTest() {

consoleIn = new BufferedReader

(new InputStreamReader(System.in));

rand = new Random();

}

//读取用户输入行

String getCommandLine() throws IOException {

System.out.print(">");

System.out.flush();

String commandLine = consoleIn.readLine();

if (commandLine == null)

return "Quit";

if (commandLine.length() == 0)

return "Quit";

else

return commandLine;

}

//从用户输入行中提取命令,

//格式化为:首字符大写,其余字符小写

//返回格式化后的命令

String extractCommand(String commandLine) {

StringTokenizer t = new StringTokenizer(commandLine);

String cmd = t.nextToken().toLowerCase();

return cmd.substring(0,1).toUpperCase()

+ cmd.substring(1);

}

//从用户输入行中提取参数,

//创建ArgumentHolder类型的对象a以封装所有参数

//错误格式的整数被视为字符串

//返回ArgumentHolder类型的对象,即封装后的参数

ArgumentHolder extractArguments(String cmd) {

StringTokenizer t = new StringTokenizer(cmd);

int tokenCount = t.countTokens();

ArgumentHolder a = new ArgumentHolder();

String token = t.nextToken();

while(t.hasMoreTokens()) {

token = t.nextToken();

try {

int i = Integer.parseInt(token);

a.setArgument(i);

}

catch (NumberFormatException e) {

a.setArgument(token);

}

}

return a;

}

//以下6个以meth开头的函数实现本测试程序

//接受的合法命令的具体处理过程。

//函数的命名规则为:meth+格式化后的用户命令

public String methAdd(int i1, int i2) {

return Integer.toString(i1) + " + " +

Integer.toString(i2) + " = " + Integer.toString(i1 + i2);

}

public String methConcat(String s1, String s2) {

return "the concatenated string is " + s1 + s2;

}

public String methHelp() {

final String[] helpMessages =

{"DynaCallTest Version 1.0",

"valid commands are:",

"add int1 int2",

"concat string1 string 2",

"help",

"minmax int1 int2 int3",

"quit",

"rand"

};

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

System.out.println(helpMessages[i]);

return "";

}

public String methMinmax(int i1, int i2, int i3) {

return ("min = " +

Integer.toString(java.lang.Math.min

(java.lang.Math.min(

i1,i2),i3)) + ", max = " + Integer.toString(

java.lang.Math.max(java.lang.Math.max(i1,i2),i3)));

}

public String methQuit() {

return "quitting";

}

public String methRand() {

return "the random number is "

+ Integer.toString(rand.nextInt());

}

//处理用户在命令行中的输入

//调用extractCommand以生成对应于用户输入的方法名

//调用extractArguments以封装用户输入参数

//调用Invoker.dynaCall以实现命令处理

String processCommand(String cmd) {

try {

String meth = "meth" + extractCommand(cmd);

ArgumentHolder a = extractArguments(cmd);

return (String)(Invoker.dynaCall(this, meth,a));

}

catch (NoSuchMethodException e) {

return "no method to process command " + cmd;

}

catch (InvocationTargetException e) {

System.out.println("trace:");

e.printStackTrace();

return "InvocationTargetException processing command" + cmd;

}

catch (IllegalAccessException e) {

System.out.println("trace:");

e.printStackTrace();

return "IllegalAccessException processing command" + cmd;

}

}

//主函数,调用processCommand以实现程序功能

public static void main(String args[]) {

boolean allOK = true;

String line;

DynaCallTest myClient = new DynaCallTest();

System.out.println("DynaCallTest Version 1.0");

System.out.println("Enter command at the prompt");

System.out.println("Type help for help");

while(allOK) {

try {

line = myClient.getCommandLine();

if (line == null)

allOK = false;

else {

System.out.println(myClient.processCommand(line));

if (line.substring(0,1).toUpperCase().equals("Q"))

allOK = false;

}

}

catch (IOException e) {

e.printStackTrace();

allOK = false;

}

}

System.exit(0);

}

}

//--------------------------------------

//类Invoker

//实现函数的动态调用

//方法:

// dynaCall

// 参数 Object c希望调用函数(方法)所在对象

// String m希望调用的方法名称

// ArgumentHolder a传递给被调用方法的参数

//-----------------------------------------

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

public class Invoker {

static Object dynaCall(Object c,String m,

ArgumentHolder a) throws NoSuchMethodException,InvocationTargetException,IllegalAccessException {

//由于java支持方法名称的重载

//(同一类中出现多于一个的同名函数),

//所以getMethod方法使用两个参数:

//字符串形式的方法名称和数组形式

//的调用参数类列表。返回值为类Method的一个对象,

//该对象和将要被

//调用的方法相关联

Method meth = c.getClass().getMethod(m, a.getArgumentClasses());

//通过类Method对象的invoke方法动态调用希望调用的方法

return (meth.invoke(c, a.getArguments()));

}

}

Java所有函数都是动态的_Java中的函数动态调用相关推荐

  1. java中函数_java中的函数

    函数的概述 1.函数定义: 能完成特定功能的代码段就是函数,每一个函数都是一个独立的小功能 2.为什么要有: 如果没有函数,在实现一个功能时候,就要写一遍这个逻辑, 如果功能多次使用,就会产生大量重复 ...

  2. concat函数_三、P57-61 MySQL中常用函数

    本部分主要讲解MySQL数据库中常用函数的使用. P57 SQL中的函数类型:字符串函数.数值函数.日期和时间函数.流程函数.其他常用函数: P58 第1部分:字符串函数 1.concat函数 con ...

  3. Layui框架下:JS中根据后台查询到的数据动态往div中ul里面动态添加li

    Layui框架下:JS中根据后台查询到的数据动态往div中ul里面动态添加li 先建立好一个div和ul JS代码: $(function () { layui.admin.req({ url: _s ...

  4. java动态代理_Java代理模式及动态代理详解

    Java的动态代理在实践中有着广泛的使用场景,比如最场景的Spring AOP.Java注解的获取.日志.用户鉴权等.本篇文章带大家了解一下代理模式.静态代理以及基于JDK原生动态代理. 代理模式 无 ...

  5. java中栈和堆都存哪些东西_java中栈内存与堆内存(JVM内存模型)

    java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...

  6. java split函数的用法_java中split函数用法以及注意事项

    java中split函数用法以及注意事项 发布时间:2020-04-23 10:28:23 来源:亿速云 阅读:215 作者:小新 本篇文章和大家了解一下java中split函数用法以及注意事项.有一 ...

  7. java中的主函数_java中main函数解析

    从写java至今,写的最多的可能就是主函数 public static void main(String[] args) {} 但是以前一直都没有问自己,为什么要这么写,因为在c语言中就没有这样子的要 ...

  8. java中main()函数的返回值是什么_Java中main()函数的返回值类型是什么

    Java中main()函数的返回值类型是什么 答:void 在单纯形表的终表中,若非基变量的检验数有0,那么最优解 答:无穷多 中国大学MOOC: 不属于现代区位理论的是( ) 答:中心地理论 不属于 ...

  9. java环境变量都是什么意思_Java环境变量,真的还有必要配吗?

    作为年龄上堪称老鸟而技术上却是菜鸟的老菜鸟,为了祖国的编程事业,不惜拿出一个月工资,淘了一台配置稍高的二手笔记本,打算与老笔记本中的撸啊撸片彻底说再见,誓要在新机种开启一番撸啊撸的新事业.当然,撸代码 ...

最新文章

  1. java为什么实现_为什么在java中这样实现了这样的实现?
  2. 华为又一战略级生态启程:华为IdeaHub 使能千行百业
  3. toolbar.netcraft.com查询域名等信息
  4. linux——shell 中的运算
  5. 网易云音乐:基于分布式图学习PGL的推荐系统优化之路
  6. Linux系统:centOS 7 忘记密码怎么办?
  7. ubuntu 改linux密码忘了怎么办,Ubuntu 14.04忘记root密码的解决方法
  8. 论文 计算机网络安全现状的分析与对策,计算机网络安全现状的分析与对策(学年论文).pdf...
  9. Java 8 之后,还有哪些进化的功能?
  10. 计算机教学研讨会议记录,教学教研工作会议记录3.doc
  11. 玩耍redis遇到的问题之记录
  12. kubernetes视频教程笔记 (9)-资源清单yaml是什么 yaml的格式语法
  13. 浅谈压缩感知(十一):凸优化
  14. 百度网盘资源下载快速提速方法,无需破解
  15. 计算机术语中bug指的是,BUG是什么意思?为什么用bug代指漏洞?
  16. 1296. 聪明的燕姿
  17. c语言while(*p *q),C语言经典例题和答案
  18. 如何在线制作gif图片?
  19. HTML5传送带视差图片展示js特效
  20. OpenGL基本图元

热门文章

  1. 下载java免安装包_下载并获取免安装版的JDK、JRE和源码包
  2. 【Web前端】一文带你吃透HTML(上篇)
  3. linux中更换apt的源
  4. 勒索软件_使您的团队投入运营,以持续进行勒索软件防御
  5. eBay买家号养号攻略
  6. 鸿蒙二维码开发Zxing
  7. JAVA化妆品销售网,区块链技术基于SSM的化妆品销售网站、基于JavaWeb的化妆品在线商城源码...
  8. 使用adb启动应用时报错 Security exception: Permission Denial: starting Intent
  9. SpringMVC前后端交互
  10. 提高腾讯QQ(电脑版)语音通话、视频聊天和远程协助的稳定性的方法