JavaRush /Java 博客 /Random-ZH /用Java编译

用Java编译

已在 Random-ZH 群组中发布
在 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