JavaRush /Java Blog /Random-TW /用Java編譯

用Java編譯

在 Random-TW 群組發布
在 IDE 中編程很棒:程式碼依賴的連貫性、方便的調試、清晰的測試、深色主題。所以,多虧了IDE,開發才得以突飛猛進的發展。但她放鬆了。每天,開發人員都沉浸在 IDE 的功能中,習慣透過一個按鈕進行提交或透過兩次點擊進行建置。 Java 編譯 - 1對於那些從一開始就在 IDE 中工作而忽略了命令列上的工作的程式設計新手來說,情況要糟糕得多。例如,在 Intellij IDEA 中,Java 應用程式的編譯透過底部面板中的載入欄來演示,所有編譯參數、類路徑處理和 Java 生活的其他樂趣都保留在幕後。我們建議討論在沒有 IDE 的情況下用 Java 進行編譯。若要執行本文中的範例,請確保您的電腦上安裝了 JDK 1.7 或更高版本。

如何編譯程式?

程式設計中的編譯是將原始程式碼縮減為字節碼,以供程式隨後啟動。從原始碼到程式啟動的操作順序如下所示:
  1. 原始碼位於名為 ClassName.java 的檔案中;
  2. 如果程式碼中沒有錯誤,則將其編譯為字節碼(在檔案 ClassName.class 中);
  3. 程序開始。
通常,每個程式都包含在單獨的目錄中。作為一個簡單的例子,讓我們將輸出輸出到控制台:
class Test {
   public static void main(String[] args) {
      System.out.println("Это говорит приложение из командной строки");
   }
}

javac指令有什麼用?

好了,第一點已經完成了。我們再進一步了解:如何編譯?:) javac 命令將幫助我們完成此操作,其參數必須指示所需的檔案:

javac Test.java
如果程式碼中沒有錯誤,Test.class 檔案將會出現在 Test.java 檔案旁邊。這是編譯後的字節碼。現在需要啟動它。這裡我們使用 java 命令,它運行字節碼: Java 編譯 - 2螢幕截圖顯示我們在輸出中得到了一些象形文字:顯然,這是一個損壞的編碼。通常這發生在 Windows 系統上。要在控制台中正確顯示西里爾字母,有以下命令:

REM change CHCP to UTF-8
CHCP 65001
CLS
它們在目前視窗的持續時間內變更目前的 shell 程式碼頁。讓我們再試一次:

D:\Java>java Test
這是應用程式在命令列中所說的內容。了解 javac 命令的工作原理非常有用,因為該命令是任何專案建置系統的基礎。

編譯並運行多個類

要使用多個類,您需要一個類路徑。它類似於包含類別的檔案系統,套件充當資料夾。此時,值得考慮將原始程式碼檔案與編譯檔案分開。通常,原始碼位於 src 目錄中,編譯後的類別位於 bin 中。例如,我們有一個類別Box和一個BoxMachine包含方法的類別main。班級Box
package src;

public class Box {
   private double size;

   public Box(double size) {
       this.size = size;
   }

   public String toString() {
       return "Box have size " + size;
   }
}
它在 src 包中,這個需要修復。班級BoxMachine
package src;

public class BoxMachine {
   public static void main(String[] args) {
       for(int  i = 0; i < 5; i++) {
           System.out.println(new Box(Math.random()*10));
       }
   }
}
這個類別也可以在 src 套件中找到。在該方法中main,它創建了五個不同大小的類別對象Box,並將有關它們的資訊顯示到控制台。要編譯這組類,您需要使用主目錄(包含 src 和 bin 資料夾)中的 javac 命令以及參數:

javac -d bin ./src/*
-d— 一個標誌,您應該在該標誌後指示已編譯類別的位置。這非常方便,因為例如轉移 1000 個課程是一個非常耗費人力的過程。 bin- 資料夾名稱。 ./src/*— 原始檔的位置。*表示必須編譯所有檔案。現在編譯的類別出現在 bin 資料夾中。要運行它們,請使用同一目錄中的 java 命令,也附帶參數:

java -classpath ./bin BoxMachine
-classpath— 一個標誌,您應該在該標誌後指示已編譯類別的位置。Java 將在此目錄中尋找主類別和所有相關類別。 ./bin— 已編譯類別所在資料夾的名稱。 BoxMachine— 主類別的名稱。與第一種情況一樣,不應指定.class,因為這是類別的名稱,而不是檔案的名稱。 結論:

D:\Java>java -classpath ./bin src.BoxMachine
Box have size 4.085985295359718
Box have size 8.63682158248986
Box have size 6.027448124299726
Box have size 7.288317703877914
Box have size 1.106181659384694

建立 JAR 文件

為了使程式易於移植和運行,您可以將編譯後的類別收集到一個 jar 檔案中 - 一個類別存檔。與 zip 或 rar 存檔的主要區別在於存在清單檔案。此清單指定了執行 jar 檔案時將運行的主類、類路徑以及許多附加資訊。讓我們在主目錄中建立一個manifest.mf 檔。其內容如下:

main-class: src.BoxMachine
class-path: bin/
main-classmain指定包含該方法並將在啟動時執行的 類別。class-path— 已編譯類別或附加程式庫的路徑。現在是時候使用 jar 指令在沒有 IDE 的情況下建立一個真正的程式了:

jar -cmf manifest.mf box-machine.jar  -C bin .
-cmf— 一個標誌,您應該在其後指定清單檔案的路徑。 manifest.mf— 清單的路徑。 box-machine.jar— 輸出 jar 檔案的名稱。 — 一個標誌,其後指示已編譯類別的路徑。 .— jar 檔案放置的路徑。在我們的例子中,這是主目錄。現在您可以啟動了。啟動jar檔案也是使用java指令完成的,但你需要指定標誌-jar:它指示正在啟動Jar文件,第二個參數是檔案的路徑jar,包括副檔名:

java -jar box-machine.jar
結論:

Box have size 5.5495235762547965
Box have size 9.695870044165662
Box have size 2.3408385788129227
Box have size 7.2790741216674135
Box have size 2.3620854470160513

不使用 IDE 進行 Java 編譯:建置系統概述

儘管命令列相對易於使用,但使用它來建立中型和大型專案卻非常困難。這需要花費大量時間並且充滿不同程度的錯誤。幸運的是,組裝系統可以讓工作過程變得更容易。透過多個團隊,該系統可以組裝任何複雜程度的項目,並且在此類系統存在期間創建的大量插件可以消除幾乎所有令人頭痛的問題。

如何編譯Java?

最著名的 Java 建置系統是 Ant、Maven 和 Gradle。沒有好壞之分:它們都是為了解決某些問題而創建的。讓我們更詳細地看看它們中的每一個。

螞蟻

Ant 是一個建置工具,它使用使用 xml 檔案描述的腳本。xml檔案結構:
<?xml version="1.0"?>
<project name="NameПроекта" default="сценарийПоУмолчанию">
    <target name="NameСценария">
  //  Действия сценария
        <echo>Hello, World!</echo>
    </target>
  //  Второй сценарий
  //  И тд
</project>
讓我們在主目錄中建立一個 build.xml 文件,其中包含以下內容:
<?xml version="1.0"?>
<project name="BoxMachine" default="test">
   <target name="test">
       <echo>First build in Ant!</echo>
   </target>
</project>
在同一目錄下,呼叫ant指令:

D:\Java>D:\Temp\ant\bin\ant
Buildfile: D:\Java\build.xml

test:
     [echo] First build in Ant!

BUILD SUCCESSFUL
Total time: 0 seconds
此標記<target>可以指定允許您管理程式集和檔案系統的各種任務。Ant 有超過 150 個可用指令,文件中列出了這些指令。在下面的範例中,我們僅使用 5 個:
  • mkdir - 建立目錄
  • delete- 刪除檔案和目錄
  • javac- Java程式碼編譯
  • java- 運行編譯後的程式碼
簡單的編譯、建置或清理腳本如下所示:
<?xml version="1.0"?>
<project name="BoxMachine" default="compile">
   <target name="compile">
       <mkdir dir="result/classes"/>
       <javac destdir="result/classes" includeantruntime="false">
           <src path="src"/>
       </javac>
   </target>
   <target name="run" depends="compile">
       <java classname="BoxMachine" classpath="result/classes"/>
   </target>
   <target name="clean">
       <delete dir="result"/>
   </target>
</project>
該腳本描述了三個操作 - compile、 、code>run 和cleancompile建立一個包含類別的結果目錄,然後使用 javac 將類別編譯到建立的目錄中。 run使用 java 命令運行編譯後的類別。 clean刪除結果目錄。如果您在主目錄中執行不帶任何參數的 ant 指令,則會執行編譯操作。如果需要執行特定操作,則在參數中指定。

D:\Java>D:/Temp/ant/bin/ant compile
Buildfile: D:\Java\build.xml

compile:
    [mkdir] Created dir: D:\Java\result\classes
    [javac] Compiling 2 source files to D:\Java\result\classes

BUILD SUCCESSFUL
Total time: 1 second

梅文

Maven 提供了一種稍微不同的建置專案的方法。在這裡,開發人員描述了他的專案和他使用的附加工具,這與 Ant 不同,在 Ant 中,建置是一系列操作。Maven 因其簡單的依賴管理以及與所有開發環境的方便整合而受到開發人員的歡迎。使用 Maven 時,我們遵循以下專案結構: Java 編譯 - 3建置規則、依賴項等在 pom.xml 檔案中描述。通常它位於主項目資料夾中。啟動時,Maven 檢查檔案結構和語法,並警告您錯誤。在主目錄的bin和src資料夾旁邊,建立一個pom.xml文件,在裡面新增:
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>ru.javarush.testmaven</groupId>
  <artifactId>testMavenWithoutIde</artifactId>
  <version>1.0.0</version>

  <build>
     <defaultGoal>compile</defaultGoal>
     <sourceDirectory>src</sourceDirectory>
     <outputDirectory>bin</outputDirectory>
     <finalName>${project.artifactId}-${project.version}</finalName>
  </build>
</project>
接下來,在命令列中執行 mvn 命令:

D:\Java>mvn
[INFO] Scanning for projects...
[INFO]
[INFO] -------------< ru.javarush.testmaven:testMavenWithoutIde >--------------
[INFO] Building testMavenWithoutIde 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ testMavenWithoutIde ---
[WARNING] Using platform encoding (Cp1251 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Java\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ testMavenWithoutIde ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding Cp1251, i.e. build is platform dependent!
[INFO] Compiling 2 source files to D:\Java\bin
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.521 s
[INFO] Finished at: 2019-06-25T20:18:05+03:00
[INFO] ------------------------------------------------------------------------
現在 bin 資料夾中有一個 src 資料夾,其中包含已編譯的類別。在pom.xml中,build標籤定義了建置的目的-編譯、原始碼和編譯結果檔的目錄以及專案名稱。Maven 具有各種建置目標和插件,用於運行測試、建立 Jar 檔案、建置發行版和其他任務。

搖籃

這是最年輕的建置系統,基於 Ant 和 Maven。主要區別在於它基於非循環圖來確定任務的順序。這對於更複雜的任務非常有用,例如增量和多項目建置。使用 Gradle 建置時,也建議堅持 Maven 專案資料夾結構。順便說一句,Gradle 中建置的檔案名為 build.gradle,看起來比 Maven 小得多。我們的課程範例:
apply plugin: 'java'
apply plugin: 'application'

sourceSets {
   main {
       java {
           srcDirs 'src'
       }
   }
}
sourceSets.main.output.classesDir = file("bin")

mainClassName = "src.BoxMachine"

defaultTasks 'compileJava', 'run'
該檔案包含插件,定義了原始程式碼檔案的目錄(如果不使用Maven專案結構)、建置結果的目錄、主類別的名稱和預設任務。build.gradle檔案所在目錄中的gradle指令負責啟動建置:

d:\Java>D:\Temp\gradle\bin\gradle

Welcome to Gradle 5.4.1!

Here are the highlights of this release:
 - Run builds with JDK12
 - New API for Incremental Tasks
 - Updates to native projects, including Swift 5 support

For more details see https://docs.gradle.org/5.4.1/release-notes.html

Starting a Gradle Daemon (subsequent builds will be faster)

> Task :help

Welcome to Gradle 5.4.1.

To run a build, run gradle <task> ...

To see a list of available tasks, run gradle tasks

To see a list of command-line options, run gradle --help

To see more detail about a task, run gradle help --task <task>

For troubleshooting, visit https://help.gradle.org

BUILD SUCCESSFUL in 52s
1 actionable task: 1 executed

結論

乍一看,在沒有 IDE 的情況下編譯和彙編程式碼的能力似乎毫無用處。事實上,當有一個帶有插件的舒適 IDE、自動檢查所有可能的內容(現代 IDE 不檢查 IQ 等級)並與流行系統整合時,為什麼還要費心使用命令列和 Google 搜尋所有命令呢?然而,實踐表明,在沒有開發環境的情況下組裝程式碼並理解該過程的每一步的能力是非常必要的。這項技能將為您和您的公司節省大量的神經細胞和時間。您可以在 JavaRush 學習如何使用 IDE、練習編寫程式碼,當然還可以了解 Java 程式設計的基礎知識。是時候回去學習了:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION