Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 转换函数的字符串表示形式';s参数列表到实际参数,用于反射调用_Java_Parsing_Reflection - Fatal编程技术网

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-ed函数本身正下方的私有静态函数

我正在编写的应用程序将读取源代码文件(包含JavaDoc块的文件,其中存在这些字符串函数调用),并创建*.java文件的副本,该文件随后将由
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,我希望它是一个