簡體   English   中英

為什么 Groovy 編譯器顯然會生成 1.5 版本的 Java?

[英]Why does Groovy compiler apparently produce 1.5 version of Java?

在 JSE 版本之間存在一些差異問題之后,我嘗試記錄用於編譯的 Java 編譯器版本(實際上是 Groovy 2.1.9、Grails 2.3.8、Java 1.7.0_60)。

經過一番翻找,我構建了這段代碼來讀取類的前導字節 - 請參閱/http://en.wikipedia.org/wiki/Java_class_file#General_layout

(更改類的路徑以匹配包名稱):

class CompilerVersionSupport {

  public static String getVersion() {
    String classAsPath = 'com/my/organisation/CompilerVersionSupport.class';
    InputStream stream = (new CompilerVersionSupport()).getClass().getClassLoader().getResourceAsStream(classAsPath);
    DataInputStream ins = new DataInputStream (stream)

    assert( ins.readUnsignedShort() == 0xcafe )    
    assert( ins.readUnsignedShort() == 0xbabe )
    int minor = ins.readUnsignedShort();
    int major = ins.readUnsignedShort();
    ins.close();
    int javaVersion = major - 44 
    return "1.$javaVersion"
    }     
}

問題是,它返回 1.5。

會發生什么?

  • 查爾斯

Groovy 的默認行為是不使用與所使用的 JDK 相同的字節碼版本來編譯代碼。 出於兼容性原因,恕我直言,1.5 是默認值。 如果您希望編譯器輸出更新的字節碼,則需要明確設置。

例如,如果您使用 Maven 編譯代碼,則可以使用GMavenPlus插件。 請參閱targetBytecode參數的說明。

如果您不使用 Maven,則可以使用-Dgroovy.target.bytecode=1.7或研究特定構建工具的可能性

如果您使用 Maven 作為構建工具,那么很可能它使用gmavenplus-plugin來編譯 Groovy。 為了找出生成的字節碼的目標 Java 版本,我進入了我的應用程序使用的gmavenplus-plugin的 pom: ~/.m2/repository/org/codehaus/gmavenplus/gmavenplus-plugin/1.5/gmavenplus-plugin-1.5.pom

在那個文件中我看到了這個,注意<javaVersion/>

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <mavenVersion>2.2.1</mavenVersion>
    <coberturaPluginVersion>2.7</coberturaPluginVersion>
    <javadocPluginVersion>2.10.1</javadocPluginVersion>
    <!-- these are properties so integration tests can use them -->
    <javaVersion>1.5</javaVersion>
    <dependencyPluginVersion>2.10</dependencyPluginVersion>
    <compilerPluginVersion>3.2</compilerPluginVersion>
    <junitVersion>4.12</junitVersion>
    <surefirePluginVersion>2.18.1</surefirePluginVersion>
    <pluginPluginVersion>3.4</pluginPluginVersion>
    <!-- this is a property so that site generation can use it -->
    <sourcePluginVersion>2.4</sourcePluginVersion>
    <!-- this is a property so that site generation and integration tests can use it -->
    <groovyVersion>2.4.1</groovyVersion>
  </properties>
...
<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compilerPluginVersion}</version>
        <configuration>
          <source>${javaVersion}</source>
          <target>${javaVersion}</target>
        </configuration>
      </plugin>

我將 IntelliJ 用於 IDE。 IntelliJ 會自動將語言級別設置為 Java 1.5。 即使我更改它,當我重新導入項目時,它也會重置回 Java 1.5(我已經模糊了敏感信息),

在此處輸入圖片說明

我認為問題在於您用來查找課程版本的程序。 如果斷言未啟用,則流不會讀取前兩個無符號短整型,因此隨后的次要和主要讀取語句分別導致 0Xcafe 和 0xbabe。 嘗試啟用斷言或嘗試使用 if 檢查。

public static String getVersion() throws Exception {
    String classAsPath = "com/my/organisation/CompilerVersionSupport.class";
    InputStream stream = (new CompilerVersionSupport()).getClass().getClassLoader().getResourceAsStream(classAsPath);
    DataInputStream ins = new DataInputStream(stream);

    if(ins.readUnsignedShort() != 0xcafe) throw new AssertionError("Invalid Class");
    if(ins.readUnsignedShort() != 0xbabe) throw new AssertionError("Invalid Class");
    int minor = ins.readUnsignedShort();
    int major = ins.readUnsignedShort();
    ins.close();
    int javaVersion = major - 44;
    return "1." + javaVersion;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM