麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

Java中的函數動態調用

2019-11-18 13:57:40
字體:
來源:轉載
供稿:網友

---- 相 信 有 不 少 人 使 用C 語 言 的 函 數 指 針 實 現 過 函 數 的 動 態 調 用。 適 當 地 運 用 函 數 動 態 調 用 功 能 不 僅 能 減 少 代 碼 數 量, 而 且 對 于 增 加 程 序 的 可 讀 性 和 易 維 護 性 也 帶 來 極 大 幫 助。 由 于java 不 支 持 指 針 功 能, 所 以 運 用 指 針 實 現 動 態 調 用 不 適 用 于java。 本 文 提 出 了 一 種 運 用java Reflection API 實 現java 函 數 動 態 調 用 的 方 法, 并 給 出 一 個 基 本 實 現 和 測 試 實 例。

---- 函 數 動 態 調 用 的 一 個 最 為 常 見 的 應 用 場 合 在 于 取 消 對 于switch 關 鍵 詞 的 依 賴。switch 關 鍵 詞 用 來 判 斷 條 件, 并 分 別 給 出 處 理 過 程 即 處 理 函 數。 一 個 典 型 的 函 數 具 有 函 數 名、 輸 入 值、 返 回 值。 而 實 現 動 態 調 用 的 關 鍵 之 處 在 于 調 用 時 得 到 正 確 的 類 名、 函 數( 方 法) 名、 以 統 一 的 格 式 實 現 參 數 的 傳 遞。 下 面 是 實 現 該 功 能 的 類Invoker,ArgumentHolder 的 清 單:

//--------------------------------------
//類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()));
}
}

//-------------------------------------
//類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.InputStreamReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.Math;
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);
}
}

---- 以 上 程 序 在jdk 1.1.4,win95 環 境 下 編 譯 通 過, 并 在linux(Slackware96),Windows Nt 4.0 ( 工 作 站) 下 經 過 驗 證。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 91福利免费视频 | 国产精品麻豆一区二区三区 | 国产精品久久av | 精品久久久久久 | 在线观看av国产一区二区 | 国产福利视频在线观看 | 国产亚洲精品久久久久久网站 | 国产三级在线观看a | 欧美精品在线视频观看 | 免费a视频 | 久久精品性视频 | 男女亲热网站 | 欧美大逼网 | 亚洲精品永久视频 | 久久丝袜脚交足黄网站免费 | 日本搞逼视频 | 91短视频网址 | www.99re14.com| 欧美精品 | 国产伦精品一区二区三区在线 | 噜噜噜在线 | 国产精品久久久久久久不卡 | 免费国产视频大全入口 | 美女黄网站免费观看 | 91午夜免费视频 | 极品一级片 | 成人免费毛片片v | 国产一区在线免费 | xvideos korean | 香蕉视频1024| 男女无套免费视频 | 国产精品久久久久久婷婷天堂 | 欧洲成人精品 | 欧美日韩免费观看视频 | 精品国产一区二区三区四区阿崩 | 在线看一区二区三区 | 久久精品亚洲一区二区 | 国产女厕所| 成人福利在线 | 国产亚洲精久久久久久蜜臀 | 久久精品a一级国产免视看成人 |