Java 如何在Groovy中调用简单的getter方法?

Java 如何在Groovy中调用简单的getter方法?,java,methods,reflection,groovy,gradle,Java,Methods,Reflection,Groovy,Gradle,我不敢相信我会问这个问题,真的很困惑。这个问题的目的是找出为什么和/或找到一种比反思更容易得到正确结果的方法 背景故事 我通过URLClassLoader从目录和jar文件加载了一些类文件,我想转储所有类名及其声明的方法。无法初始化这些类(请参见false),因为如果在这些类中运行任何代码,可能会由于某些缺少的依赖项而引发异常。我在尝试只输出类名时遇到了这个问题 问题: 我缺少的是什么,我如何绕过Groovy的魔力,在对象(类型为java.lang.Class)上调用一个方法(称为getName

我不敢相信我会问这个问题,真的很困惑。这个问题的目的是找出为什么和/或找到一种比反思更容易得到正确结果的方法

背景故事 我通过
URLClassLoader
从目录和jar文件加载了一些类文件,我想转储所有类名及其声明的方法。无法初始化这些类(请参见
false
),因为如果在这些类中运行任何代码,可能会由于某些缺少的依赖项而引发异常。我在尝试只输出类名时遇到了这个问题

问题: 我缺少的是什么,我如何绕过Groovy的魔力,在对象(类型为
java.lang.Class
)上调用一个方法(称为
getName
),而不进行反射?也请有人指出规格说明,说明为什么这样做。
以下是我的迷你测试(见下文)的输出和我的评论:

.name // magically initializes class X and calls X.get("name")
name and Y

.getName() // tries to reload class Y in another ClassLoader and initialize it
X and thrown SHOULD NOT INIT

["name"] // this is just plain magic! What a Terrible Failure :)
name and thrown SHOULD NOT INIT

reflection // obviously works, becase it's really explicit
X and Y
测试线束和测试用例 将测试闭包更改为参数类型上的显式(
Class c->
)没有任何区别

新文件(“X.java”).write(“”)
公共X类{
公共静态字符串get(字符串键){
返回键;
}
}
''');
新文件(“Y.java”).write(“”)
公共Y类{
静止的{
if(true)//需要防止编译错误
抛出新的UnsupportedOperationException(“不应初始化”);
}
}
''');
打印“javacx.javay.java”.execute().err.text;
def test={字符串标题,闭包名称->
URL=新文件(“.”.toURI().toul();
//每次都需要一个新的类加载器,因为它会记住
//如果类已经抛出ExceptionInInitializeError
ClassLoader=java.net.URLClassLoader.newInstance(url);
//false表示不初始化该类。
//要获取类的名称,无需初始化
//如反射测试所示。
//即使字段和方法也可以在不初始化的情况下读取,
//它本质上只是解析.class文件。
Class x=Class.forName(“x”,false,loader);
Class y=Class.forName(“y”,false,loader);
println()
印刷品名称
试一试{
打印姓名(x)
}捕获(可丢弃的ex){
打印“抛出”+ex.cause?消息
}
打印“和”
试一试{
打印名称(y)
}捕获(可丢弃的ex){
打印“抛出”+ex.cause?消息
}
println()
}
测试'.name',{c->c.name;}
测试'.getName()',{c->c.getName();}
测试'[“名称”]',{c->c[“名称”]}
测试“反射”{c->java.lang.Class.Class.getDeclaredMethod(“getName”).invoke(c);}

对于invokedynamic端口,我可以给出一个明确的答案:绕过JVM错误,JVM调用类的静态方法,而根本不调用clinit


至于另一部分。。。。这可能是因为我不知道塞德里克为什么这么做。假设JVM能够正常工作,就不需要这样做

您能更清楚地了解“invokedynamic”和“other”吗?我对低级别JVM还不熟悉。你知道有没有一种方法可以像我一样使用反射而不使用反射吗?至于InvokedDynamic。。。在JVM上,要进行方法调用,您需要知道接收方和参数基类型以及方法名称。如果您希望使用不同的逻辑,而不是在编译时就必须知道所有这些类型,例如,因为您是一种动态语言,那么您就不能使用这些标准调用指令。它有三个方面:反射、运行时类生成和invokedynamic。Groovy使用了所有这些。反射和invokedynamic最终也会在运行时生成类……但是invokedynamic允许您编写一个伪方法调用,然后为缓存和方法选择提供您自己的逻辑。虽然要为invokedynamic或运行时生成的类生成信息,您通常使用reflectionSo,但实际上没有办法绕过反射。方法调用本身可以在没有反射的情况下完成,就像invokedynamic和运行时类生成一样(尽管在Groovy中,类生成的第一次调用仍然使用反射)