Java 转换函数的字符串表示形式';s参数列表到实际参数,用于反射调用
更新:在得到一个意想不到的好答案后,我在这个问题的底部添加了一些上下文,确切地说明了我将如何使用这些字符串函数调用 我需要翻译一个字符串,例如 转换为对该函数的反射调用。获取包、类和函数名不是问题。我已经开始使用自己的解决方案来解析参数列表,确定每个参数的类型并返回适当的对象 (我将类型的范围限制为八个基本类型加上字符串。Java 转换函数的字符串表示形式';s参数列表到实际参数,用于反射调用,java,parsing,reflection,Java,Parsing,Reflection,更新:在得到一个意想不到的好答案后,我在这个问题的底部添加了一些上下文,确切地说明了我将如何使用这些字符串函数调用 我需要翻译一个字符串,例如 转换为对该函数的反射调用。获取包、类和函数名不是问题。我已经开始使用自己的解决方案来解析参数列表,确定每个参数的类型并返回适当的对象 (我将类型的范围限制为八个基本类型加上字符串。null将被视为一个字符串,逗号和双引号必须使用一些简单的标记进行严格的转义,例如\uu DBL\u QT\uu,以避免在逗号上取消和拆分的复杂情况。) 我不是在问如何通过字符
null
将被视为一个字符串,逗号和双引号必须使用一些简单的标记进行严格的转义,例如\uu DBL\u QT\uu
,以避免在逗号上取消和拆分的复杂情况。)
我不是在问如何通过字符串解析来实现这一点,因为我知道如何实现。这只是一个很大的工作,我希望有一个解决方案已经存在。不幸的是,这是如此通用的术语,我在搜索方面一无所获
我理解,要求外部现有图书馆是离题的。我只是希望在它关闭之前得到一些反馈,甚至是一个更好的搜索词的建议。或者,可能会有一种完全不同的方法被建议
多谢各位
背景: 每个函数调用都位于函数的JavaDoc块中,代表一段示例代码——它的源代码或它的
System.out
output——将显示在该位置
这些参数用于自定义其显示,例如
- 压痕
- 消除不相关的部分(如许可证块),以及
- 对于JavaDoc,链接最重要的函数。 这种定制主要用于源代码表示,但也可以应用于其输出
JavaDoc
处理
因此,对于每个示例代码,可能会有两个,甚至更多的字符串函数调用。可能还有更多,因为我可能想在不同的上下文中展示同一个示例的不同部分——可能整个示例都在整个类JavaDoc块中,而其中的片段则在该类的相关函数中
我已经编写了解析源代码(包含JavaDoc块的源代码,它与读取示例代码的源代码是分开的),并使用insert example code here
和insert example code output here
标记盲目地重新输出其源代码的过程
现在,我在字符串字段中的InsertExampleCode
对象中调用了这个字符串函数。现在我需要做这个问题顶部描述的事情。找出他们想要调用的函数,并执行此操作。将#
更改为一个点(
),围绕它编写一个类定义,以便您拥有一个有效的Java源文件,在类路径中包含tools.jar
,并调用com.sun.tools.javac.Main
创建自己的ClassLoader
实例来加载已编译的类,并运行它(使其实现一个有用的接口,例如java.util.concurrent.Callable
,以便轻松获得调用的结果)
这就应该做到了。我为此创建的类,称为,是一个重要的部分,用于翻译每个标记的“customizer”部分,这是一个自定义标记输出的函数 (.只有codelet和xbnjava必须在类路径中。) 字符串签名示例(以小标记为单位):
{@.codelet.and.out.com.github.aliteralmind.codelet.examples.adder.AdderDemo%eliminateCommentBlocksAndPackageDecl()}
自定义程序部分是百分号(%
)后面的所有内容。此自定义项仅包含函数名和空参数。这意味着函数必须存在于少数严格指定的类集中
{@.codelet.and.out.com.github.aliteralmind.codelet.examples.adder.AdderDemo%lineRange(1,false,“adder adder”,2,false,“println(adder.getSum())”,“^”)}
这也指定了参数,根据设计,这些参数是“简单的”——非空字符串或基元类型
{@.codelet.and.out.com.github.aliteralmind.codelet.examples.adder.AdderDemo%com.github.aliteralmind.codelet.examples.LineRangeWithLinksCompact#AdderDemo\u lineSnippetWithLinks()}
指定函数所在的显式包和类
由于这些标记的性质以及字符串签名的实现方式,我决定坚持直接字符串解析而不是动态编译
SimpleMethodSignature
的两个示例用法:
在第一个示例中,完整签名(包、类和函数名,包括其所有参数)在字符串中指定
import com.github.aliteralmind.codelet.simplesig.SimpleMethodSignature;
import com.github.xbn.lang.reflect.InvokeMethodWithRtx;
import java.lang.reflect.Method;
public class SimpleMethodSigNoDefaults {
public static final void main(String[] ignored) {
String strSig = "com.github.aliteralmind.codelet.examples.simplesig." +
"SimpleMethodSigNoDefaults#getStringForBoolInt(false, 3)";
SimpleMethodSignature simpleSig = null;
try {
simpleSig = SimpleMethodSignature.newFromStringAndDefaults(
String.class, strSig, null, null,
null); //debug (on=System.out, off=null)
} catch(ClassNotFoundException cnfx) {
throw new RuntimeException(cnfx);
}
Method m = null;
try {
m = simpleSig.getMethod();
} catch(NoSuchMethodException nsmx) {
throw new RuntimeException(nsmx);
}
m.setAccessible(true);
Object returnValue = new InvokeMethodWithRtx(m).sstatic().
parameters(simpleSig.getParamValueObjectList().toArray()).invokeGetReturnValue();
System.out.println(returnValue);
}
public static final String getStringForBoolInt(Boolean b, Integer i) {
return "b=" + b + ", i=" + i;
}
}
输出:
b=false, i=3
b=false, i=3
第二个示例演示未指定(包和)类名的字符串签名。直接提供函数必须存在的潜在类
import com.github.aliteralmind.codelet.simplesig.SimpleMethodSignature;
import com.github.xbn.lang.reflect.InvokeMethodWithRtx;
import java.lang.reflect.Method;
public class SimpleMethodSigWithClassDefaults {
public static final void main(String[] ignored) {
String strSig = "getStringForBoolInt(false, 3)";
SimpleMethodSignature simpleSig = null;
try {
simpleSig = SimpleMethodSignature.newFromStringAndDefaults(
String.class, strSig, null,
new Class[]{Object.class, SimpleMethodSigWithClassDefaults.class, SimpleMethodSignature.class},
null); //debug (on=System.out, off=null)
} catch(ClassNotFoundException cnfx) {
throw new RuntimeException(cnfx);
}
Method m = null;
try {
m = simpleSig.getMethod();
} catch(NoSuchMethodException nsmx) {
throw new RuntimeException(nsmx);
}
m.setAccessible(true);
Object returnValue = new InvokeMethodWithRtx(m).sstatic().
parameters(simpleSig.getParamValueObjectList().toArray()).invokeGetReturnValue();
System.out.println(returnValue);
}
public static final String getStringForBoolInt(Boolean b, Integer i) {
return "b=" + b + ", i=" + i;
}
}
输出:
b=false, i=3
b=false, i=3
这些都是我从未做过的事情,但这是一个令人印象深刻的想法,使我的整个方法毫无意义。没有用于
javac
的API,我希望它是一个