JAVA 基础_JDK8-Tools 学习(一)

JDK包括JRE和开发工具,如javac编译器,用于将Java源代码编译成字节码。JRE仅包含运行时环境,如JVM和类库。javac命令用于编译Java程序,支持多种选项以控制编译行为,如-g用于生成调试信息,-classpath指定类路径,-d指定输出目录。文章还介绍了编译过程和自定义编译器插件的概念。
摘要由CSDN通过智能技术生成

JDK组成结构

官网地址:https://docs.oracle.com/javase/8/docs/index.html
在这里插入图片描述
JDK 在大的层级上可以分为开发工具和 jre 组成,而 jre 则由类库和 jvm 组成。

JDK = 开发工具(Tools & Tool APIs)  + JRE
JRE = 类库 + 虚拟机(Java Virtual Machine)

问题:jdk 和 jre 的关联关系是怎样的?

JDK(Java Development Kit)和JRE(Java Runtime Environment)是Java平台的两个主要组件。它们之间的关系如下:

  1. JDK 包含了 JRE,并且还包含了开发过程中需要的编译器(javac)、调试器、JavaDoc等工具和测试框架等开发工具。
  2. JRE 只包含了运行Java应用程序所需的组件,如Java虚拟机(JVM)、基础类库、java命令,以及一些需要的配置文件。

简单的说,JDK 就是开发Java程序所需要的开发工具和运行时环境,而JRE只包含了运行Java程序的运行时环境。如果你只需要运行Java程序,那只需要安装JRE就可以了。但如果你需要进行开发,那就需要安装JDK。

另外,需要注意的是,JDK同样也包含了JRE,但JRE不包含JDK。因此,如果你需要使用JDK,就无需单独安装JRE了;如果你只需要运行Java程序,那么只需要安装JRE即可。

总之,Java开发需要安装JDK,而运行Java程序只需要安装JRE即可。

此次重点学习 tools


java

java 命令是 JDK(Java Development Kit)中的一个重要命令,通常我们使用它来启动和运行 Java 应用程序。

命令格式

在 JDK 中,java 命令通常的用法格式如下:

java [options] class [args...]

其中:

  • options:是指控制 JVM 行为的命令行选项,例如 -server 表示启用服务器性能模式,-Xmx256m 表示将 Java 堆内存最大限制设置为 256MB 等。
  • class:是指应用程序的主类(Main Class)名称,当 JVM 启动时,它会自动在 classpath 指定的路径中寻找该类的字节码文件,并加载该类的代码。
  • args:是指运行该 Java 应用程序时所需要的命令行参数,例如我们可以将 java MyProgram arg1 arg2 作为启动命令行,在 MyProgram.java 中使用 System.out.println(args[0])System.out.println(args[1]) 来获取到从命令行传递的参数内容。

除了以上的基本语法之外,java 命令还支持一些常用的选项:

  • -classpath-cp: 为 Java 虚拟机指定类搜索路径,可以是目录、JAR 文件,也可以是类目录和类路径组成的一连串的字符串。例如,在启动 MyProgram 时指定两个 classpath 目录 /path/to/classes:/path/to/other/classes,可以使用 java -cp /path/to/classes:/path/to/other/classes MyProgram arg1 arg2 命令行启动 MyProgram 应用程序。
  • -version:用来显示当前 JVM 的版本信息。
  • -server:启用服务器模式,在大型应用程序或者需要长时间运行的服务中,这个选项可以提高 JVM 运行效率和吞吐量。
  • -Xmx-Xms:指定 Java 堆的最大内存和初始内存大小。
  • -verbose:class-verbose:gc:开启类加载日志与垃圾回收日志,这些选项可以让我们更好地了解 Java 应用程序的性能状况。
  • -D:用于在启动时配置 Java 系统属性,可以通过 -Dproperty=value 的形式传递多个参数。例如,可以通过 -Dmyconfig=/path/to/config.properties 为应用程序传递配置文件的路径。

生产场景及其参数使用

在 JVM 启动 Java 应用程序时,可以使用不同的选项来控制 JVM 的行为,这些选项可以帮助我们优化和调试应用程序,或者解决某些特殊场景下的问题。下面是一些常见的选项以及它们的应用场景:

  1. -Xmx<size>:指定 Java 堆的最大内存大小。例如,-Xmx1g 表示最大内存为 1GB。这个选项可以帮助我们调整 Java 程序的内存占用量,避免 OutOfMemoryError 导致的程序崩溃。

  2. -Xms<size>:指定 Java 堆的初始内存大小。例如,-Xms256m 表示初始内存为 256MB。这个选项可以用于优化 JVM 启动时间,或者调整特定应用程序的内存分配策略。

  3. -Xss<size>:指定线程的最大栈大小。例如,-Xss512k 表示线程栈的大小上限为 512KB。这个选项可以控制线程栈的大小,避免因为线程数太多导致内存溢出。

  4. -XX:MaxPermSize=<size>:指定永久代的最大容量大小。例如,-XX:MaxPermSize=256m 表示最大容量为 256MB。这个选项只对 JDK 7 以前的版本有效,可以用于解决永久代内存溢出等问题。

  5. -XX:+UseG1GC:开启 G1 垃圾回收器,在处理大规模数据和高并发场景时提供更好的性能表现。

  6. -XX:+PrintGCDetails-XX:+PrintGCDateStamps:分别用于打印垃圾回收的详细信息和时间戳信息。这些选项可以帮助我们了解垃圾回收的行为和性能状况。

  7. -XX:+HeapDumpOnOutOfMemoryError:在发生 OutOfMemoryError 错误时自动生成堆内存快照。这个选项可以帮助我们快速定位内存泄漏或者程序缓慢等问题。

  8. -XX:CompileThreshold=<value>:指定方法的编译阈值。例如,-XX:CompileThreshold=1000 表示当一个方法被执行 1000 次时,就会被编译成本地代码。这个选项可以优化方法的执行速度,但是可能会导致启动时间延长。

这些选项都是非常常用的,它们可以帮助我们优化和调试 Java 程序。需要注意的是,不同的 JVM 实现和版本可能会支持不完全相同的选项,负责开发运维的同学需要能够熟练掌握这些选项的使用方法,并根据具体情况做出调整。

除了上述提到的常用选项,还有以下几个比较常见的选项:

  1. -verbose:class:开启类加载日志,用于打印类加载器的信息,包括所加载的类的名称、加载时间、来源等。可以用于调试类加载的问题。

  2. -D:用于添加 Java 系统属性,可以通过 -Dproperty=value 的形式指定,例如-Djava.net.preferIPv4Stack=true。在某些场景下,例如解决网络连接问题,需要添加特定的系统属性。

  3. -server:启用服务器模式,会对 JVM 的初始化、编译和垃圾回收等方面做出一些优化,适用于高并发/长时间运行的企业级应用程序。

  4. -XX:OnOutOfMemoryError=<cmd>:在发生 OutOfMemoryError 错误时执行指定的命令,可以用于自动执行垃圾收集或者暂时终止 JVM 等操作。

  5. -XX:PermSize=<size>:指定永久代的初始大小。例如,-XX:PermSize=128m 表示初始大小为 128MB。需要注意的是,在 JDK 8 以后的版本中,永久代已经被元空间(Metaspace)取代,因此该选项已经被废弃。

  6. -XX:-UseGCOverheadLimit:关闭 GC 频繁发生的检查,可以避免在部分系统中因为 GC 太频繁导致程序崩溃的问题。

这些选项都是常用的,可以根据具体需要选择使用。需要注意的是,在使用这些选项时,应该谨慎调整,以防止因为误操作导致程序崩溃或者性能下降。

除了以上列举的常见选项,还有一些比较特殊的选项,可以用于特殊场景下的调试和优化,例如:

  1. -XX:+PrintFlagsFinal:打印 JVM 各种参数的默认值和当前值,用于了解 JVM 配置的具体情况。

  2. -XX:+PrintCommandLineFlags:打印当前 JVM 启动时使用的所有命令行选项,可以用于验证 JVM 配置是否正确。

  3. -XX:+UnlockDiagnosticVMOptions-XX:+UnlockExperimentalVMOptions:这两个选项可以解锁一些 JVM 实验性的选项和诊断性的选项,例如启用线程轨迹诊断工具、打印 JVM 内部调试信息等。

  4. -XX:+UseSerialGC:使用串行垃圾收集器,适用于小型单线程应用程序。

  5. -XX:+UseConcMarkSweepGC:使用 CMS 垃圾收集器,适用于高并发大内存应用程序。

  6. -XX:+UseParallelGC:使用并行垃圾收集器,适用于多核多线程的应用程序。

  7. -XX:+UseParallelOldGC:使用并行老年代垃圾收集器,适用于大内存应用程序。

这些选项都是比较特殊的,需要了解具体的使用场景和效果。在使用这些选项时,建议先进行测试和验证,避免因为误操作导致系统不稳定或出现性能问题。

用法: java [-options] class [args...]
           (执行类)
   或  java [-options] -jar jarfile [args...]
           (执行 jar 文件)
其中选项包括:
    -d32          使用 32 位数据模型 (如果可用)
    -d64          使用 64 位数据模型 (如果可用)
    -server       选择 "server" VM
                  默认 VM 是 server.

    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>; 分隔的目录, JAR 档案
                  和 ZIP 档案列表, 用于搜索类文件。
    -D<名称>=<>
                  设置系统属性
    -verbose:[class|gc|jni]
                  启用详细输出
    -version      输出产品版本并退出
    -version:<>
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  需要指定的版本才能运行
    -showversion  输出产品版本并继续
    -jre-restrict-search | -no-jre-restrict-search
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  在版本搜索中包括/排除用户专用 JRE
    -? -help      输出此帮助消息
    -X            输出非标准选项的帮助
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  按指定的粒度启用断言
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  禁用具有指定粒度的断言
    -esa | -enablesystemassertions
                  启用系统断言
    -dsa | -disablesystemassertions
                  禁用系统断言
    -agentlib:<libname>[=<选项>]
                  加载本机代理库 <libname>, 例如 -agentlib:hprof
                  另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
    -agentpath:<pathname>[=<选项>]
                  按完整路径名加载本机代理库
    -javaagent:<jarpath>[=<选项>]
                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
    -splash:<imagepath>
                  使用指定的图像显示启动屏幕
有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html。

更详细的参阅官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html

javac

javac 是 JDK 中自带的编译器,是 Java 编程语言的一部分。它可以将 Java 代码编译成字节码,并生成相应的类文件。

1. Java 编译过程

Java 代码的编译过程可以分为三个步骤:编辑、编译和运行。

编辑:使用文本编辑器或者集成开发环境(IDE)撰写 Java 代码。

编译:使用 javac 编译器将 Java 代码编译成字节码(也就是 .class 文件),字节码是运行在 Java 虚拟机(JVM)上的。

运行:使用 java 命令运行已经编译好的字节码文件。

2. Java 编译器的使用方法

javac 编译器通常通过命令行方式使用。下面是一个简单的示例:

javac HelloWorld.java

这个命令会将 HelloWorld.java 文件编译成 HelloWorld.class 文件。

3. 编译器选项

javac 编译器还提供了一些选项,这些选项可以在编译 Java 代码时指定,用于控制编译的行为。

C:\Users\Administrate>javac
用法: javac <options> <source files>
其中, 可能的选项包括:
  -g                         生成所有调试信息
  -g:none                    不生成任何调试信息
  -g:{lines,vars,source}     只生成某些调试信息
  -nowarn                    不生成任何警告
  -verbose                   输出有关编译器正在执行的操作的消息
  -deprecation               输出使用已过时的 API 的源位置
  -classpath <路径>            指定查找用户类文件和注释处理程序的位置
  -cp <路径>                   指定查找用户类文件和注释处理程序的位置
  -sourcepath <路径>           指定查找输入源文件的位置
  -bootclasspath <路径>        覆盖引导类文件的位置
  -extdirs <目录>              覆盖所安装扩展的位置
  -endorseddirs <目录>         覆盖签名的标准路径的位置
  -proc:{none,only}          控制是否执行注释处理和/或编译。
  -processor <class1>[,<class2>,<class3>...] 要运行的注释处理程序的名称; 绕过默认的搜索进程
  -processorpath <路径>        指定查找注释处理程序的位置
  -parameters                生成元数据以用于方法参数的反射
  -d <目录>                    指定放置生成的类文件的位置
  -s <目录>                    指定放置生成的源文件的位置
  -h <目录>                    指定放置生成的本机标头文件的位置
  -implicit:{none,class}     指定是否为隐式引用文件生成类文件
  -encoding <编码>             指定源文件使用的字符编码
  -source <发行版>              提供与指定发行版的源兼容性
  -target <发行版>              生成特定 VM 版本的类文件
  -profile <配置文件>            请确保使用的 API 在指定的配置文件中可用
  -version                   版本信息
  -help                      输出标准选项的提要
  -A关键字[=]                  传递给注释处理程序的选项
  -X                         输出非标准选项的提要
  -J<标记>                     直接将 <标记> 传递给运行时系统
  -Werror                    出现警告时终止编译
  @<文件名>                     从文件读取选项和文件名

例如:

  1. -classpath 选项

该选项用于添加类路径,指定 javac 编译器查找类的位置。例如:

javac -classpath .;lib/* com/example/Main.java

该命令指定了当前目录 .lib 目录下的 jar 文件作为类路径,在编译 Main.java 文件时,需要用到这些类。

  1. -d 选项

该选项指定编译后的 .class 文件输出的目录。例如:

javac -d bin com/example/Main.java

该命令将编译后的 .class 文件输出到 bin 目录中。

  1. -encoding 选项

该选项用于指定源代码文件的字符编码格式。例如:

javac -encoding UTF-8 com/example/Main.java

该命令指定了源代码文件的字符编码格式为 UTF-8。

  1. -source-target 选项

这两个选项用于指定编译的 Java 版本和生成的字节码版本。例如:

javac -source 1.8 -target 1.8 com/example/Main.java

该命令指定编译的 Java 版本为 1.8,生成的字节码版本也为 1.8。

  1. -g 选项

该选项用于生成调试信息,以方便在开发过程中使用调试器进行调试。例如:

javac -g com/example/Main.java

该命令表示在编译时生成调试信息。

  1. -nowarn 选项

该选项用于关闭编译器产生的警告信息。例如:

javac -nowarn com/example/Main.java

该命令表示关闭编译器产生的警告信息。

  1. -verbose 选项

该选项用于在编译过程中提供更多的详细信息。例如:

javac -verbose com/example/Main.java

该命令会在编译过程中提供更多的详细信息,以帮助了解编译过程中发生了什么。

这些选项在实际开发中可以根据需要进行组合和使用。例如在实际开发中常用的命令是:

javac -d bin -cp .;lib/* -source 1.8 -target 1.8 -g com/example/Main.java

该命令将源代码文件编译为 .class 文件,并将 .class 文件输出到 bin 目录中。使用 lib 目录下的 jar 文件作为类路径,指定编译时的版本为 1.8,生成的字节码版本也为 1.8,生成调试信息以方便调试。

还有一些常用的选项,比如:

  1. -XDignore.symbol.file=true 选项

该选项用于忽略缺少类文件的错误信息。例如:

javac -XDignore.symbol.file=true com/example/Main.java

该命令会在编译时忽略缺少类文件的错误信息。

  1. -Xlint 选项

该选项用于检测代码中的一些语法和潜在的问题。例如:

javac -Xlint:unchecked com/example/Main.java

该命令会检测未经检查的转换并生成相应的警告信息。

  1. -bootclasspath 选项

该选项用于指定引导类路径,以便编译器可以找到系统类库。例如:

javac -bootclasspath /path/to/jre/lib/rt.jar com/example/Main.java

该命令会在编译时使用指定的 rt.jar 文件作为系统类库。

以上是 javac 常见的选项及其适用场景。在实际开发中,我们可以根据具体的需求和情况,灵活地使用这些选项,以便更好地完成编译任务。

详情可以查看 javac 命令的帮助文档:https://docs.oracle.com/javase/8/docs/technotes/guides/javac/index.html

4. 编译器的原理

javac 编译器的原理是将 Java 代码编译成字节码,字节码是一种与平台无关的中间代码格式,可以在不同的平台上运行。

编译器首先将 Java 代码进行词法和语法分析,生成抽象语法树(AST)。然后进行语义分析,检查是否存在语法错误和类型错误。最后,将 AST 转换为字节码文件。

javac 编译器还支持增量编译,即只对修改过的源代码进行重新编译,提高编译速度。

综上所述,javac 是 JDK 中自带的 Java 编译器,可以将 Java 代码编译成字节码,并生成 .class 文件。javac 编译器还提供了一些选项,用于控制编译的行为,例如 -classpath-sourcepath-d 选项等。

javac 编译器是 Java 程序的编译器,它将 Java 源文件编译成字节码文件,这些字节码文件可以在 Java 虚拟机(JVM)中运行。在 javac 编译 Java 程序时,会经过以下几个主要的编译步骤:

  1. 词法分析(Lexical Analysis):将 Java 代码分解成一系列的 Token。

  2. 语法分析(Syntax Analysis):将 Token 形成的序列组合成语法树,检测语法错误并生成抽象>语法树(AST)。

  3. 语义分析(Semantic Analysis):检查语法树中存在的错误,确认类型、解析符号引用等。

  4. 代码生成(Code Generation):将 AST 转换为 Java 字节码文件。

下面分别进行详细解释:

  1. 词法分析:在 javac 中,主要工作是将源代码的字符流分割成一个个的 Token,这些 Token 是>语言的基本单元,以便后续的处理。例如,对于 int x = 1;语句,javac 将其分解成以下的 Token:
[IDENTIFIER:int][IDENTIFIER:x][OPERATOR:=][NUMERIC LITERAL:1][SEMICOLON:;]
  1. 语法分析:在词法分析后,javac 将 Token 组合成语法树,主要是对语法结构进行分析和检>>查。如果语法存在错误,例如缺少分号或者括号不匹配等,编译器就会报错并且停止运行。例如,对于下面的语句,javac 将生成以下的语法树:
int x = 1;
BlockStatement
   VariableDeclarationsStatement
       VariableDeclaration
           PrimitiveType: int
           VariableDeclarator
               Identifier: x
               NumericLiteral: 1
   ;
  1. 语义分析:在语法分析后,javac 将检查 AST 中是否存在错误,例如变量的类型是否正确,方法的参数和返回值是否匹配等。此外,javac 还会解析符号引用,确认标识符的含义和定义位置。例如,javac 将检查下面的方法是否存在错误:
public void sayHello() {
   System.out.println("Hello, world!");
}
  1. 代码生成:在语义分析之后,javac 将使用上述的语法树和语义信息生成 Java 字节码文件。字节码文件可以在 JVM 中运行,并被转化为机器指令,执行 Java 代码。

以上就是 javac 编译器的流程和原理,可以帮助我们深入了解 Java 代码是如何从源代码转换到执行代码的。然而,在实际的开发中,我们可以不必深入了解这些细节,只需要了解常用的编译选项和调试技巧即可。

5. 自定义编译器插件

javac 编译器还支持自定义插件。开发者可以通过编写插件,扩展 javac 编译器的功能,例如实现自定义的语法检查、注解处理、代码生成等功能。

自定义插件需要实现 javax.tools.JavaCompiler 接口。开发者可以使用 ServiceLoader 类来加载自定义插件,并将插件注册到编译器中。

下面是一个简单的示例,展示如何编写一个简单的 javac 插件:

public class SimplePlugin implements CompilerPlugin {

    @Override
    public String getName() {
        return "SimplePlugin";
    }

    @Override
    public void init(JavacTask task, String... args) {
        // 初始化插件
    }

    @Override
    public void process(JavacTask task, Set<? extends Kind> kinds, 
			Iterable<? extends CompilationUnitTree> units, 
			CompilationUnitTree root) {
        // 处理编译过程中的 AST
    }
}

上面的 SimplePlugin 类实现了 CompilerPlugin 接口,通过覆盖 getName()init()process() 方法来编写插件。init() 方法用于初始化插件,process() 方法用于处理编译过程中的抽象语法树(AST)。

6. 其他扩展

除了自定义插件,javac 编译器还提供了一些其他的扩展机制,注解处理器(Annotation Processor)和编译时注解(Compile-Time Annotation)等。这些扩展机制可以帮助开发者更加便捷地编写和维护 Java 代码。

注解处理器和编译时注解可以用于生成编译器的元数据信息,例如生成配置文件、XML 文件等等。这样做可以减少手动编写配置文件的工作量,同时也可以避免人工错误导致的问题。

综上所述,javac 编译器是 Java 语言的一部分,主要用于将 Java 代码编译成字节码,并生成相应的 .class 文件。它还支持一些扩展机制,例如自定义插件、注解处理器和编译时注解等,可以帮助开发者更好地编写和维护 Java 代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值