JavaRush /จาวาบล็อก /Random-TH /การคอมไพล์ใน Java

การคอมไพล์ใน Java

เผยแพร่ในกลุ่ม
การเขียนโปรแกรมใน IDE นั้นยอดเยี่ยม: ความเชื่อมโยงของการขึ้นต่อกันของโค้ด การดีบักที่สะดวก การทดสอบที่ชัดเจน ธีมสีเข้ม ดังนั้น ต้องขอบคุณ IDE ที่ทำให้การพัฒนาพัฒนาอย่างก้าวกระโดด แต่เธอก็ผ่อนคลาย ทุกๆ วัน นักพัฒนาจะคุ้นเคยกับการทำงานของ IDE โดยใช้เวลาเพียงปุ่มเดียวหรือสร้างอาคารด้วยการคลิกสองครั้ง การคอมไพล์ใน Java - 1สถานการณ์แย่ลงมากสำหรับผู้ที่เพิ่งเริ่มเขียนโปรแกรมซึ่งทำงานใน IDE ตั้งแต่เริ่มต้นโดยไม่สนใจงานบนบรรทัดคำสั่ง ตัวอย่างเช่น ใน Intellij IDEA การคอมไพล์แอปพลิเคชัน Java จะแสดงโดยแถบโหลดในแผงด้านล่าง และพารามิเตอร์การคอมไพล์ทั้งหมด การประมวลผลคลาสพาธ และความพึงพอใจอื่นๆ ของชีวิต Java ยังคงอยู่เบื้องหลัง เราขอแนะนำให้พูดคุยเกี่ยวกับการคอมไพล์ใน Java โดยไม่มี IDE หากต้องการเรียกใช้ตัวอย่างในบทความนี้ ตรวจสอบให้แน่ใจว่าได้ติดตั้ง JDK 1.7 ขึ้นไปบนเครื่องของคุณแล้ว

จะคอมไพล์โปรแกรมได้อย่างไร?

การคอมไพล์ในการเขียนโปรแกรมคือการลดซอร์สโค้ดให้เป็นไบต์โค้ดเพื่อเริ่มโปรแกรมครั้งต่อไป ลำดับการดำเนินการตั้งแต่ซอร์สโค้ดไปจนถึงการเปิดตัวโปรแกรมมีลักษณะดังนี้:
  1. มีซอร์สโค้ดในไฟล์ชื่อ ClassName.java;
  2. หากไม่มีข้อผิดพลาดในโค้ด โค้ดนั้นจะถูกคอมไพล์เป็น bytecode (ในไฟล์ ClassName.class)
  3. โปรแกรมเริ่มต้นขึ้น
โดยปกติแล้ว แต่ละโปรแกรมจะอยู่ในไดเร็กทอรีที่แยกจากกัน เป็นตัวอย่างง่ายๆ ให้เรานำเอาต์พุตไปที่คอนโซล:
class Test {
   public static void main(String[] args) {
      System.out.println("Это говорит приложение из командной строки");
   }
}

คำสั่ง javac ใช้ทำอะไร?

เอาล่ะ ประเด็นแรกเสร็จแล้ว เรามาทำความเข้าใจกันต่อ: จะคอมไพล์อย่างไร? :) คำสั่ง javac จะช่วยเราในเรื่องนี้ โดยอาร์กิวเมนต์จะต้องระบุไฟล์ที่ต้องการ:

javac Test.java
หากไม่มีข้อผิดพลาดในโค้ด ไฟล์ Test.class จะปรากฏถัดจากไฟล์ Test.java นี่คือรหัสไบต์ที่คอมไพล์แล้ว ตอนนี้มันต้องเปิดตัวแล้ว ที่นี่เราใช้คำสั่ง java ซึ่งรัน bytecode: การคอมไพล์ใน Java - 2ภาพหน้าจอแสดงให้เห็นว่าเราได้รับอักษรอียิปต์โบราณในเอาต์พุต แน่นอนว่านี่เป็นการเข้ารหัสที่เสียหาย โดยทั่วไปสิ่งนี้จะเกิดขึ้นบนระบบ Windows หากต้องการแสดงตัวอักษรซีริลลิกในคอนโซลอย่างถูกต้อง ให้ใช้คำสั่งต่อไปนี้:

REM change CHCP to UTF-8
CHCP 65001
CLS
พวกเขาเปลี่ยนหน้าโค้ดเชลล์ปัจจุบันในช่วงระยะเวลาของหน้าต่างปัจจุบัน ลองอีกครั้ง:

D:\Java>java Test
นี่คือสิ่งที่แอปพลิเคชันพูดจากบรรทัดคำสั่ง การทราบว่าคำสั่ง javac ทำงานอย่างไรมีประโยชน์มาก เนื่องจากคำสั่งนี้เป็นพื้นฐานของระบบ build โปรเจ็กต์ใดๆ

การคอมไพล์และรันหลายคลาส

หากต้องการทำงานกับหลายคลาส คุณต้องมี classpath มันคล้ายกับระบบไฟล์ที่มีคลาสอยู่และแพ็คเกจทำหน้าที่เป็นโฟลเดอร์ ณ จุดนี้ ควรพิจารณาแยกไฟล์ซอร์สโค้ดออกจากไฟล์ที่คอมไพล์แล้ว ตามกฎแล้ว แหล่งที่มาจะอยู่ในไดเร็กทอรี 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ที่มีขนาดต่างกัน และแสดงข้อมูลเกี่ยวกับออบเจ็กต์เหล่านั้นบนคอนโซล ในการคอมไพล์กลุ่มคลาสนี้ คุณต้องใช้คำสั่ง javac จากไดเร็กทอรีหลัก (ซึ่งมีโฟลเดอร์ src และ bin) พร้อมด้วยอาร์กิวเมนต์:

javac -d bin ./src/*
-d— แฟล็กหลังจากนั้นคุณควรระบุตำแหน่งที่คลาสที่คอมไพล์จะไป ซึ่งสะดวกมาก เนื่องจากการโอน เช่น 1,000 คลาสเป็นกระบวนการที่ต้องใช้แรงงานมาก 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 ถูกดำเนินการ, classpath และข้อมูลเพิ่มเติมจำนวนมาก มาสร้างไฟล์ manifest.mf ในไดเร็กทอรีหลักกัน เนื้อหาจะมีดังนี้:

main-class: src.BoxMachine
class-path: bin/
main-classระบุคลาสที่มีวิธีการmainและจะดำเนินการเมื่อเริ่มต้นระบบ class-path— เส้นทางไปยังคลาสที่คอมไพล์แล้วหรือไลบรารีเพิ่มเติม ตอนนี้ได้เวลาสร้างโปรแกรมจริงโดยไม่ต้องใช้ IDE โดยใช้คำสั่ง jar:

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

การคอมไพล์ใน Java โดยไม่มี IDE: ภาพรวมของระบบบิลด์

แม้ว่าการใช้บรรทัดคำสั่งจะค่อนข้างง่าย แต่ก็เป็นเรื่องยากมากที่จะสร้างโครงการขนาดกลางและขนาดใหญ่โดยใช้บรรทัดคำสั่งนี้ การดำเนินการนี้ใช้เวลานานและเต็มไปด้วยข้อผิดพลาดในระดับที่แตกต่างกัน โชคดีที่มีระบบการประกอบที่ทำให้กระบวนการทำงานง่ายขึ้นมาก ด้วยหลายทีม ระบบนี้สามารถรวบรวมโปรเจ็กต์ที่มีความซับซ้อนได้ และปลั๊กอินจำนวนมากที่สร้างขึ้นระหว่างการมีอยู่ของระบบดังกล่าวสามารถขจัดอาการปวดหัวได้เกือบทุกอย่าง

จะคอมไพล์ Java ได้อย่างไร?

ระบบ Java build ที่มีชื่อเสียงที่สุดคือ 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 และclean. compileสร้างไดเร็กทอรีผลลัพธ์ที่มีคลาสอยู่ในนั้น จากนั้นใช้ 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 ที่ซึ่งบิลด์นั้นเป็นลำดับของการดำเนินการ 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] ------------------------------------------------------------------------
ขณะนี้มีโฟลเดอร์ src ในโฟลเดอร์ bin ซึ่งมีคลาสที่คอมไพล์แล้ว ใน pom.xml แท็ก build จะกำหนดวัตถุประสงค์ของการ 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) ไดเร็กทอรีผลลัพธ์ของบิลด์ ชื่อของคลาสหลัก และงานเริ่มต้น คำสั่ง gradle ในไดเร็กทอรีที่มีไฟล์ build.gradle มีหน้าที่รับผิดชอบในการเริ่ม build:

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 ดูเหมือนจะไร้ประโยชน์ เหตุใดจึงต้องกังวลกับบรรทัดคำสั่งและคำสั่งทั้งหมดของ Google ในเมื่อมี IDE ที่สะดวกสบายพร้อมปลั๊กอิน การตรวจสอบทุกสิ่งที่เป็นไปได้โดยอัตโนมัติ (IDE สมัยใหม่ไม่ตรวจสอบระดับ IQ) และการรวมเข้ากับระบบยอดนิยม อย่างไรก็ตาม จากการปฏิบัติแสดงให้เห็นว่าความสามารถในการรวบรวมโค้ดโดยไม่มีสภาพแวดล้อมการพัฒนาและการทำความเข้าใจทุกขั้นตอนของกระบวนการนี้มีความจำเป็นอย่างยิ่ง ทักษะนี้จะช่วยประหยัดเซลล์ประสาทและเวลาได้มากสำหรับคุณและบริษัท คุณสามารถเรียนรู้วิธีใช้ IDE ฝึกเขียนโค้ด และแน่นอนว่ารับความรู้พื้นฐานของการเขียนโปรแกรม Java ได้ที่นี่ ที่ JavaRush ได้เวลากลับไปเรียนรู้ :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION