难题,高手进来解决一下证明你的实力

lijiahuioooo 2009-12-11 11:02:00
rule=“int getvar(double para){ int fvda=0;
if(para>=1000 && para<1000000) fvda=0;
else if(para<1002) fvda=2;
else if(para>=999999 && para<9999999999)
fvda=2;return fvda;}"
这个方法是从数据库查出来的字符串

怎么把这个字符串还原成方法,并且我可以调用它

...全文
294 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
ScAREcrOw_ss 2009-12-14
  • 打赏
  • 举报
回复
等待JAVA7吧。
realreachard 2009-12-14
  • 打赏
  • 举报
回复
可以通过这个东西来留个后门什么的,呵呵呵
realreachard 2009-12-14
  • 打赏
  • 举报
回复
学习
wtuihpl 2009-12-14
  • 打赏
  • 举报
回复
呵呵,还真用了eval功能··楼主结贴哈!

[Quote=引用 5 楼 iamrf 的回复:]
引用 4 楼 swandragon 的回复:
在程序里把类定义和方法已字符串的形式写出到一个.java文件
动态编译,加载,反射调用


恩差不多就是这个意思,把你读出来的东西写到一个.java文件中,然后自己写个小工具类,用类加载器来加载这个写好的java文件,然后newInstance一个实例出来,就可以正常的对其调用了
[/Quote]
daisycool 2009-12-14
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 wnjok 的回复:]
12楼,盖楼盖得真好,一眼望不到边

[/Quote]

对啊,站得高才能望得远。费劲口舌也没有完整代码解释得更清楚,楼,就是这么盖滴。
daisycool 2009-12-14
  • 打赏
  • 举报
回复
/JDK_DIR/jdk1.5.0_05/lib/tools.jar
wanjunbao 2009-12-14
  • 打赏
  • 举报
回复
没有工具类·~
wanjunbao 2009-12-14
  • 打赏
  • 举报
回复
不错的代码!~
hewei_shine 2009-12-14
  • 打赏
  • 举报
回复
12楼,顶起。
timeriver_wang 2009-12-14
  • 打赏
  • 举报
回复
12楼,盖楼盖得真好,一眼望不到边
mianfeidog 2009-12-14
  • 打赏
  • 举报
回复
膜拜12楼,要是能给import com.sun.tools.javac.Main;这个工具类就完美了。
SambaGao 2009-12-14
  • 打赏
  • 举报
回复
学习了。
lyf_sust 2009-12-14
  • 打赏
  • 举报
回复
收藏了
daisycool 2009-12-14
  • 打赏
  • 举报
回复


public Object doCompile(String className) throws Exception {
int seed = (int)(100000 * Math.random());
String path = System.getProperty("java.io.tmpdir") + "/";
className += "_" + seed;

path = "";
ClassLoader loader = ClassLoader.getSystemClassLoader();

String sourceFile = path + className + ".java";

FileWriter fw = new FileWriter(sourceFile);

String code =
"import java.util.Date;\n" +
"import java.util.Calendar;\n" +
"import java.text.DateFormat;\n" +
"import java.text.SimpleDateFormat;\n\n" +
"public class " + className + "{\n" + " public " + className + "() {}\n";

code +=
" public Object calculate(String input[]) {\n" +
" " + shouldReturn(formula) + " " + substituteFormulaWithValues() + semiColon() + "\n" +
" }\n";

code +=
" public double max(double ... args) {\n" +
" double max = args[0];\n" +
" for (int i = 1; i < args.length; i ++) {\n" +
" if (args[i] > max) max = args[i];\n" +
" }\n" +
" return max;\n" +
" }\n";

code +=
" public double min(double ... args) {\n" +
" double min = args[0];\n" +
" for (int i = 1; i < args.length; i ++) {\n" +
" if (args[i] < min) min = args[i];\n" +
" }\n" +
" return min;\n" +
" }\n";

code +=
" public double sum(double ... args){\n" +
" try {\n" +
" double output = 0;\n" +
" for (int i = 0; i < args.length; i ++) {\n" +
" output += args[i];\n" +
" }\n" +
" return output;\n" +
" }\n" +
" catch (Exception ex) {\n" +
" return 0;\n" +
" }\n" +
" }\n";

code +=
" public int minusYear(String dateString, int years){\n" +
" dateString = dateString.replaceAll(\"-\", \"\");\n" +
" return year(dateString) - years;\n" +
" }\n";

code +=
" public int minusMonth(String dateString, int months){\n" +
" dateString = dateString.replaceAll(\"-\", \"\");\n" +
" return month(dateString) - months;\n" +
" }\n";

code +=
" private Calendar getCalendar(String dateString) {\n" +
" DateFormat formatter = new SimpleDateFormat(\"ddMMyyyy\");\n" +
" try {\n" +
" Date date = formatter.parse(dateString);\n" +
" Calendar cal = Calendar.getInstance();\n" +
" cal.setTime(date);\n" +
" return cal;\n" +
" } catch (Exception ex){\n" +
" ex.printStackTrace();\n" +
" }\n" +
" return null;\n" +
" }\n";

code +=
" public int year(String dateString) {\n" +
" return getCalendar(dateString).get(Calendar.YEAR);\n" +
" }\n";

code +=
" public int month(String dateString) {\n" +
" return getCalendar(dateString).get(Calendar.MONTH) + 1;\n" +
" }\n";

code +=
" public int day(String dateString) {\n" +
" return getCalendar(dateString).get(Calendar.DAY_OF_MONTH);\n" +
" }\n";

code +=
" public int week(String dateString) {\n" +
" return getCalendar(dateString).get(Calendar.WEEK_OF_YEAR);\n" +
" }\n";

code += "}\n";

System.out.println(className + ".java\n\n" + code);
fw.write(code);
fw.close();
File f = new File(sourceFile);
System.out.println("file path:"+f.getAbsolutePath());


int compileReturnCode = Main.compile(new String[] { sourceFile });
if (compileReturnCode == 0) {
Object objectParameters[] = { new String[] {} };
Class classParameters[] = { objectParameters[0].getClass() };
String packageAndClass = "au.com.taxsurvey.calculation." + className;
// Class aClass = Class.forName(packageAndClass);
Class aClass = Class.forName(path + className);
Object instance = aClass.newInstance();

Method theMethod = null;

theMethod = aClass.getDeclaredMethod("calculate", classParameters);
Object obj = theMethod.invoke(instance, objectParameters);

System.out.println("Result: " + obj);

// clean up the created files
try {
File file = new File(className + ".class");
File file2 = new File(className + ".java");
f.delete();
file.delete();
file2.delete();
} catch (Exception ex) {
ex.printStackTrace();
}

return obj;
}

return null;
}

/*************Debug********************/

/************** Test ******************/
public static void main (String args[]){
// System.out.println(DateUtility.year("28092007"));
NewCalculationHandler nch = new NewCalculationHandler();
String formula = "min(^ABC,^BCD, ^DEC, ^DLA)";
// formula = "if (^ABC > ^BCD) return ^DEC; else return ^DLA";
// formula = "(^ABC+^BCD)*^DEC-min(^DLA, ^ABC)";
// formula = "new south wales";
// formula = "if (^ABC>0) return \"greater\"; else return \"less\"";
// formula = "sum(^ABC, ^BCD, ^DEC, max(^DLA, ^DEC))";
// formula = "If(^ABC>7) return ^BCD; else return \"\";";
// formula = "month(^BCD)";
// formula = "minusYear(\"20-06-2009\", year(^BCD));";
// formula = "Sum(^FFF) + Sum(^BBB)";
formula = "^ABC + ^BCD";
Map<String, Object> values = new HashMap<String, Object>();
values.put("ABC", "8");
values.put("BCD", "9");
values.put("DEC", "\"greater\"");
values.put("DLA", "\"less\"");
values.put("FFF", "3, 4");
try {
nch.calculate(formula, values);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

System.exit(0);
}
}

============ DONE ============
daisycool 2009-12-14
  • 打赏
  • 举报
回复


/**
* This method splits the formula and extracts the varialbes.
* e.g. ^ABC + ^BCD will return {"ABC", "BCD"}
*
* @param formula
* @return String[] variables
*/
public static String[] spliter(String formula) {
int index = 0;
String temp = "";
formula += " "; // to avoid array indexOutOfBound exception
Set<String> check = new HashSet<String>();
List<String> output = new ArrayList<String>();
for (int i = 0; i < formula.length(); i++) {
index = formula.indexOf(SIGN, i);
if (index < 0)
break;
for (int n = index; n < formula.length(); n++) {
char c = formula.charAt(n + 1);
if (Character.isLetterOrDigit(c) || c == '_') {
temp += formula.charAt(n + 1);
} else {
System.out.println("Spliting: " + temp);
i = n;
break;
}
}
if (!check.contains(temp)) {
output.add(temp);
}
check.add(temp);
temp = "";
}
String out[] = new String[output.size()];
return output.toArray(out);
}

/**
* Match the tags and values
* @param values<String, String> this is the value passed from the client side
* the Servlet which receives the call will constructed this map.
*/
private void setValues(Map<String, Object> values) {
this.values = values;

Iterator keys = values.keySet().iterator();
while (keys.hasNext()) {
Object key = keys.next();
System.out.println("ValuesMap containing: Key = " + key + ", Value = " + values.get(key));
}
}

/**
* if there are missing values for the variables extracted from the formula,
* set the default value '0' for them.
*/
public void setDefaultValues() {
String variables [] = spliter(formula);

for (int i = 0; i < variables.length; i ++) {
String key = variables[i];

if (!values.containsKey(key)) {
values.put(key, "0");
}
}
}

/**
* Substitute the variables in the formula with values from the value map
*
*/
public String substituteFormulaWithValues() {
setDefaultValues();
Iterator<String> keys = values.keySet().iterator();
String output = convertToJavaCode(formula);

//if the formula is a plain string
if (spliter(formula).length == 0)
output = "\"" + output + "\"";

System.out.println("Formula that is to be substuted: " + output);
while (keys.hasNext()) {
String key = keys.next();
String theValue = values.get(key).toString();
String value = theValue;
try {
value = "" + Double.parseDouble(theValue);
}
catch (Exception ex) {
if (!isANumberArray(value)) {
value = "\"" + theValue + "\"";
}
}
output = output.replaceAll(key, value);
System.out.println("Substituting " + key + " with Value " + value);
}

System.out.println("formula = " + output);
return output;
}

public boolean isANumberArray(String input) {
String [] nums = input.split(",");
for (int i = 0; i < nums.length; i ++) {
String num = nums[i].replaceAll(" ", "");
try {
double x = Double.parseDouble(num);
}
catch (Exception ex) {
return false;
}
}

return true;
}

public String semiColon() {
if (spliter(formula).length == 0) {
return ";";
}
return "";
}

/**
* determines whether the method should return a value. This is because in formulas like
* 'if(^ABC) return ^BCD; else return ^DIW;', there's alreay 'return' kayword in it, but in
* formulas like 'max(^ABC, ^BCD)' it doesn't.
* @param formula
* @return String 'return' or ''
*/
public String shouldReturn(String formula) {
if (formula.indexOf("return") >= 0) return "";

return "return ";
}


daisycool 2009-12-14
  • 打赏
  • 举报
回复
我曾经做过一个会计软件计算税收的问题,基于不同情况有不同的计算公式,不同的变量,然后使用公式进行计算得出税务情况。为了达到灵活的目的,这些公式都以字符串的形式存储在数据库里,在具体运算过程中被程序调用。我的方法是把从数据库得到的公式动态的写到一个String方式的class里,然后即时的编译和执行得到答案,想必就是楼主想要的东西。

下面把进行编译和计算的类原封不动的贴出来,给楼主进行参考


package au.com.taxsurvey.calculation;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.sun.tools.javac.Main;


/**
* <p>Title: <b>Calculation Handler</b></p>
*
* <p>Description: This class generates another class to do the calculations based on
* the formula and the values of those variables used in the formula.
* There are only 2 steps to be applied to use this Calculation Class
* <ol>
* <li><b>Instantiate this class. e.g. NewCalculationHandler nch = new NewCalculationHandler();</b></li>
* <li><b>Call 'calculate(String formula, Map<String, String> values)</b></li><ul>
* <li>The formula is the formula used to calculate, e.g. ^ABC + ^BCD</li>
* <li>The values map is a map contains the variables and corresponding values, e.g.<br/>
* values("ABC", "28.58");<br/>
* values("BCD", "312.30");</li>
* </ul>
* </li>
* <li><b>value type for different types of operations:</b>
* <table border=1>
* <tr bgcolor="black">
* <td><b><font color=white>Keyword</font></b></td>
* <td><b><font color=white>Sample Formula</font></b></td>
* <td><b><font color=white>Map Patterns</font></b></td>
* </tr>
* <tr>
* <td><b>max</b></td>
* <td>max(^ABC, ^BCD)</td>
* <td>values("ABC", "382.32"), values("BCD", "291.17");</td>
* </tr>
* <tr>
* <td><b>min</b></td>
* <td>same as 'max'</td>
* <td>same as 'max'</td>
* </tr>
* <tr>
* <td><b>sum</b></td>
* <td>sum(^ABC)</td>
* <td>values("ABC", "382.32"), values("BCD", "291.17");</td>
* </tr>
* <tr>
* <td><b>if</b></td>
* <td>if(^ABC>^BCD) return ^BBC;</td>
* <td>values("ABC", "2"), values("BCD", "29"), values("BBC", "3")</td>
* </tr>
* <tr>
* <td><b>normal calculation</b></td>
* <td>(^ABC+^BCD)*^CDE/^BCD</td>
* <td>values("ABC", "2"), values("BCD", "29"), values("CDE", "3")</td>
* </tr>
* <tr>
* <td><b>year</b></td>
* <td>if(year(^BCD)>1)return ^DEF; return ^AFO</td>
* <td>values("BCD", "\"28092007\""); others are normal variables</td>
* </tr>
* <tr>
* <td><b>month</b></td>
* <td>if(month(^BCD)>11)return ^DEF; return ^AFO</td>
* <td>values("BCD", "\"28092007\""); </td>
* </tr>
* <tr>
* <td><b>day</b></td>
* <td>if(day(^BCD)>28)return ^DEF; return ^AFO</td>
* <td>values("BCD", "\"28092007\"");</td>
* </tr>
* <tr>
* <td><b>static string</b></td>
* <td>"New South Wales</td>
* <td>values(null, null)</td>
* </tr>
* </table>
* </li>
* </ol>
* </p>
*
* <p>Created on: 21/09/2007</p>
*
*
*/
public class NewCalculationHandler {

public final static int FIND_MAX = 1;
public final static int FIND_MIN = -1;

public final static char SIGN = '^';

public final static String MAN_AND1 = " AND ";
public final static String MAN_AND2 = " and ";

public final static String JAVA_AND = " && ";

public final static String MAN_OR1 = " OR ";
public final static String MAN_OR2 = " or ";

public final static String JAVA_OR = " || ";

public final static String MAN_SUM1 = "SUM";
public final static String MAN_SUM2 = "Sum";

public final static String JAVA_SUM = "sum";

public final static String MAN_MAX1 = "MAX";
public final static String MAN_MAX2 = "Max";

public final static String JAVA_MAX = "max";

public final static String MAN_MIN1 = "MIN";
public final static String MAN_MIN2 = "Min";

public final static String JAVA_MIN = "min";

public final static String MAN_NOT_EQUAL_TO = "NOT_EQUAL_TO";

public final static String JAVA_NOT_EQUAL_TO = "!=";

public final static String MAN_EQUAL_TO = "==";

public final static String JAVA_EQUAL_TO = "==";

public final static String MAN_GREATER_THAN = ">";

public final static String JAVA_GREATER_THAN = ">";

public final static String MAN_LESS_THAN = "<";

public final static String JAVA_LESS_THAN = "<";

public final static String MAN_IF = "If";

public final static String JAVA_IF = "if";

public final static String MAN_STRING = "\"";

public final static String JAVA_STRING = "\\\"";

public final static String MAN_NOT = "#";

public final static String JAVA_NOT = "!=";

public final static String MAN_NULL = "NULL";

public final static String JAVA_NULL = "null";

public final static String MAN_SUM_INDICATOR = "%";

public final static String JAVA_SUM_INDICATOR = "";

private Map<String, String> rules = new HashMap<String, String>();

private String formula;

// this map has the values for each variable as Map<tag, value>
// e.g. values<"^ABC", "3.23">
private Map<String, Object> values = new HashMap<String, Object>();

public String getFormula() {
return formula;
}

public void setFormula(String formula) {
this.formula = formula;
}

/**
* default constructor
* loads all rules for formula validating.
*/
public NewCalculationHandler() {
rules.put(MAN_AND1, JAVA_AND);
rules.put(MAN_AND2, JAVA_AND);
rules.put(MAN_OR1, JAVA_OR);
rules.put(MAN_OR2, JAVA_OR);
rules.put(MAN_SUM1, JAVA_SUM);
rules.put(MAN_SUM2, JAVA_SUM);
rules.put(MAN_MAX1, JAVA_MAX);
rules.put(MAN_MAX2, JAVA_MAX);
rules.put(MAN_MIN1, JAVA_MIN);
rules.put(MAN_MIN2, JAVA_MIN);
rules.put(MAN_NOT_EQUAL_TO, JAVA_NOT_EQUAL_TO);
rules.put(MAN_EQUAL_TO, JAVA_EQUAL_TO);
rules.put(MAN_GREATER_THAN, JAVA_GREATER_THAN);
rules.put(MAN_LESS_THAN, JAVA_LESS_THAN);
rules.put(MAN_IF, JAVA_IF);
rules.put(MAN_STRING, JAVA_STRING);
rules.put(MAN_NOT, JAVA_NOT);
rules.put(MAN_NULL, JAVA_NULL);
rules.put(MAN_SUM_INDICATOR, JAVA_SUM_INDICATOR);
}

/**
* it calls the method that does the actual calculation.
* @param formula formula string
* @param values map that contains the variable name as its key, and the corresponding value
* @return Object the result
* @throws Exception
*/
public Object calculate(String formula, Map<String, Object> values) throws Exception{
// if (!isValidCalculation(formula, values)) {
// throw new Exception("Value missing for the calculation. " +
// "Please check if all the variables in the formula has a value.");
// }
this.setValues(values);
this.setFormula(formula);

// this.substituteFormulaWithValues();

try {
return this.doCompile("CalculationTemp");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Failed to calculate!");
}

return null;
}

/**
* it calls the method that does the a test calculation.
* @param formula formula string
* @param values map that contains the variable name as its key, and the corresponding value
* @return Object the result
* @throws Exception
*/
public String testCalculate(String formula, Map<String, Object> values) throws Exception{
// if (!isValidCalculation(formula, values)) {
// throw new Exception("Value missing for the calculation. " +
// "Please check if all the variables in the formula has a value.");
// }
this.setValues(values);
this.setFormula(formula);

String errMsg = "";
// try {
// this.doCompile("CalculationTemp");
// }
// catch (Exception ex) {
// errMsg = "Error due to: " + ex.getMessage();
// }

return shouldReturn(formula) + " " + substituteFormulaWithValues() + "\n" + errMsg;

}

private boolean isValidCalculation(String formula, Map<String, Object> values) {
String temp [] = spliter(formula);
if (temp.length <= values.values().size()) return true;
return false;
}

/**
* replace syntaxically illegal words in the formula to JAVA readable workds to make
* the formula Java syntax
*
* @param formula
* @return JAVA format formula
*/
private String convertToJavaCode(String formula) {
String output = formula.replace(SIGN, ' ');
Iterator<String> it = rules.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
output = output.replaceAll(key, rules.get(key));
}

// if (spliter(output).length == 0) return output;

for (int i = output.length() - 1; i >= 0; i --) {
char c = output.charAt(i);
if (c == ';')
break;
else {
if (c == ' ') {
continue;
}
else {
output += ";";
break;
}
}
}

return output;
}



由于回复内容不能太长,程序分几次贴出来,LZ粘贴拷贝一下就可以了

幸亏这个方法比较复杂,我作了挺完整的Java文档,楼主可以转化出来看一下,应该挺清楚的。

这里面doCompile这个方法是关键的地方,楼主想要的东西应该就在这里。
swandragon 2009-12-11
  • 打赏
  • 举报
回复
在程序里把类定义和方法已字符串的形式写出到一个.java文件
动态编译,加载,反射调用

gao11811 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 justinavril 的回复:]
先创建一个java文件,里面定义只定义类:
Java codepublicclass Tool{

}

然后利用IO读写文件,将rule写到这个Tool类中去,最好是写成static方法,这样你就可以调用Tool.getvar()方法了。
[/Quote]

好方法,要调用java方法,需要实例
wtuihpl 2009-12-11
  • 打赏
  • 举报
回复
这个问题之前看到过,类似于动态语言,也就是javascript的eval功能。 没用过见人使用过生成一个java类然后用jdk编译一下,然后在用反射调用。楼主在搜一下吧,.net有eval功能,没准java也早已有人实现了该功能·
justinavril 2009-12-11
  • 打赏
  • 举报
回复
先创建一个java文件,里面定义只定义类:
public class Tool{

}


然后利用IO读写文件,将rule写到这个Tool类中去,最好是写成static方法,这样你就可以调用Tool.getvar()方法了。
加载更多回复(3)

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧