Groovy 脚本文件名中的禁止字符?

Nic*_*oul 4 groovy filenames hyphen

我写了一个很小的 ​​Groovy 脚本(只是一些简单的指令)并将它命名为a-b.groovy.
我的同事在运行它时遇到问题并说:

我相信“-”在 Groovy 脚本文件名中是非法的

问题: Groovy 文件名中非法字符的完整列表是什么?

(注意:与groovy 脚本文件的命名约定不同,我的问题与约定无关)

Szy*_*iak 6

最准确的答案是使用与命名 Java 类相同的命名 Groovy 脚本的标准。Groovy,类似于 Java 支持 Unicode 字符编码,您很可能可以使用任何 Unicode 字符作为脚本名称(这并不意味着您应该这样做)。

每个 Groovy 脚本都被编译为一个扩展groovy.lang.Script类的 Java类。它的名称取自 Groovy 脚本文件名。看看这个例子:

someSimpleGroovyScript.groovy

println "test"
Run Code Online (Sandbox Code Playgroud)

当我们编译它时,groovyc someSimpleGroovyScript.groovy我们会看到一个类文件someSimpleGroovyScript.class。现在,如果我们看看这个类是什么样的:

javap someSimpleGroovyScript
Run Code Online (Sandbox Code Playgroud)

我们会得到这样的东西:

Compiled from "someSimpleGroovyScript.groovy"
public class someSimpleGroovyScript extends groovy.lang.Script {
  public static transient boolean __$stMC;
  public someSimpleGroovyScript();
  public someSimpleGroovyScript(groovy.lang.Binding);
  public static void main(java.lang.String...);
  public java.lang.Object run();
  protected groovy.lang.MetaClass $getStaticMetaClass();
}
Run Code Online (Sandbox Code Playgroud)


Groovy 脚本名称的特殊情况

尽管 Java 类命名标准适用于 Groovy 脚本名称,但 Groovy 支持一些特殊情况。

-在脚本名称中使用字符

您可以将脚本命名为a-b.groovy并作为 Groovy 脚本运行:

groovy a-b.groovy
Run Code Online (Sandbox Code Playgroud)

您甚至可以编译它groovyc以获得以下 Java 类:

Compiled from "a-b.groovy"
public class a-b extends groovy.lang.Script {
  public static transient boolean __$stMC;
  public a-b();
  public a-b(groovy.lang.Binding);
  public static void main(java.lang.String...);
  public java.lang.Object run();
  protected groovy.lang.MetaClass $getStaticMetaClass();
}
Run Code Online (Sandbox Code Playgroud)

即使这个类名对于 Java 编译器不正确,你仍然可以用 Java 运行它(你需要添加groovy-all到类路径中):

java -classpath ".:./groovy-all-2.4.12.jar" a-b
Run Code Online (Sandbox Code Playgroud)

使用$脚本名称

在 Groovy 中,您甚至可以将脚本调用为,123$.groovy并且可以简单地将其运行为:

groovy 123\$.groovy
Run Code Online (Sandbox Code Playgroud)

然而$,当将此脚本编译为 Java 类时,Groovy 编译器将替换为下划线:

javap 123_
Run Code Online (Sandbox Code Playgroud)

输出:

Compiled from "123$.groovy"
public class 123_ extends groovy.lang.Script {
  public static transient boolean __$stMC;
  public 123_();
  public 123_(groovy.lang.Binding);
  public static void main(java.lang.String...);
  public java.lang.Object run();
  protected groovy.lang.MetaClass $getStaticMetaClass();
}
Run Code Online (Sandbox Code Playgroud)

您仍然可以使用 Java 运行这样的编译脚本:

java -classpath ".:./groovy-all-2.4.12.jar" 123_
Run Code Online (Sandbox Code Playgroud)

在脚本名称中使用空格

您还可以在脚本名称中使用空格,例如this is script.groovy可以执行为:

groovy this\ is\ script.groovy
Run Code Online (Sandbox Code Playgroud)

然而,Groovy 编译器会用下划线替换每个空格:

Compiled from "this is script.groovy"
public class this_is_script extends groovy.lang.Script {
  public static transient boolean __$stMC;
  public this_is_script();
  public this_is_script(groovy.lang.Binding);
  public static void main(java.lang.String...);
  public java.lang.Object run();
  protected groovy.lang.MetaClass $getStaticMetaClass();
}
Run Code Online (Sandbox Code Playgroud)

您仍然可以使用 Java 运行这样的编译脚本:

java -classpath ".:./groovy-all-2.4.12.jar" this_is_script
Run Code Online (Sandbox Code Playgroud)

使用class.groovy的脚本名称

它更进一步。您可以创建一个名为的脚本class.groovy,该脚本将编译为以下 Java 类:

Compiled from "class.groovy"
public class class extends groovy.lang.Script {
  public static transient boolean __$stMC;
  public class();
  public class(groovy.lang.Binding);
  public static void main(java.lang.String...);
  public java.lang.Object run();
  protected groovy.lang.MetaClass $getStaticMetaClass();
}
Run Code Online (Sandbox Code Playgroud)

javac编译器永远不会允许你用这样的名字编译一个类,但是java运行这样的字节码没有问题:

java -classpath ".:./groovy-all-2.4.12.jar" class
Run Code Online (Sandbox Code Playgroud)