前言:最初接触到这两个选项是在学习Maven的时候,需要配置pom.xml文件的maven.compiler.source和maven.compiler.target,当时没有深入了解,只是简单的设置为我当前使用的jdk版本8。没有出现任何问题,也就没有进一步探究。然而,今天在看JVM书籍时,在介绍Class文件内容的部分又看到关于source和target的相关介绍,我觉得是时候进行总结了。

目录

  • 概述
  • 一 .Javac编译器
    • 1、source 选项
    • 2、target选项
  • 二、应用
    • 1.Maven
    • 2. IDEA

概述

source 指定源代码使用的最高语言特性所属的Java SE版本(同JDK版本)
target 指定Class字节码可以运行的最低虚拟机版本

一 .Javac编译器

语法格式:

javac [options] [sourcefiles]

options 选项,也就是我们编译时使用的参数,例如我们常用的选项-encoding指定字符编码、-classpath指定类加载路径。

source和target是编译器的参数,我们平时并不常用到。

1、source 选项

参考官方文档

-source release (release表示JDK发行的版本号,例如1.8)

Specifies the version of source code accepted.(指定可接受的源文件版本)

The following values for release are allowed:

  • 1.6 / 6 No language changes were introduced in Java SE 6. However, encoding errors in source files are now reported as errors instead of warnings as was done in earlier releases of Java Platform, Standard Edition.
  • 1.7/7 The compiler accepts code with features introduced in Java SE 7.
  • 1.8/8 The compiler accepts code with features introduced in Java SE 8.
  • 9 The compiler accepts code with features introduced in Java SE 9.
  • 10 The compiler accepts code with features introduced in Java SE 10.
  • 11 The default value. The compiler accepts code with features introduced in Java SE 11.

如何理解指定可接受的源文件版本呢?

在可以设置的release部分,有这样一句描述:

The compiler accepts code with features introduced in Java SE ${version}
编译器接受带有某版本Java SE中引入的特性的代码

我觉得最重要的是要理解“accept”一词,查看词典

V-T If a person, company, or organization accepts something such as a document, they recognize that it is genuine, correct, or satisfactory and agree to consider it or handle it.
如果一个人、公司或组织接受某样东西,比如一份文件,他们认为或者识别它是真实的、正确的或令人满意的,并同意考虑或处理它。

Java各个发布版本的语言特性(features),如下图所示(详细信息可参考【Java语言特性】):

假如,我本地系统上安装了JDK 1.8,我编写的代码并没有使用Java SE 8中提供的语言特性,但是我使用了Java SE 5中提供的语言特性:泛型。这时我编译该代码时可以使用-source 5选项,这时JDK1.8的编译器,就不会检查Java SE 5版本以上提供的语言特性,减少了一些不必要的检查,或许能提高一些编译的性能。(注,并不会降低编译的版本,编译器的版本和JDK一致,网上的关于降低编译器版本的说法是有误的)我们平时在命令行编译文件时,并没有提供source参数,其实,默认使用了和JDK一样的版本,对于我的系统安装了的是JDK1.8,所以参数默认为-source 8,会检查Jave SE 8及以下版本的语言特性。

import java.util.ArrayList;
import java.util.List;public class Java5 {public static void main(String[] args) {List<String> words = new ArrayList<String>(); }
}

说专业一点就是,提供与指定发行版的源兼容性

在Windows的命令行窗口下,运行命令:javac,获取关于参数(或者说选项)的信息,如下图所示:


总结:source选项用于指定源文件使用的最高语言特性,以便让编译器识别并编译与特性相关的代码。source最大不能超过JDK版本(Java SE版本),例如Java SE 8,不可能提供Java SE 9的特性,所以如果你的JDK版本是8,source参数最大只能是8。source默认值和JDK版本相同。

例如,以下Java代码使用了Java SE 8的语言特性lambda表达式,我使用编译时指定-source 7

public class LambdaTest {public static void main(String[] args) {System.out.println(operate(1, 1, (a, b)->a+b));}public static int operate(int a, int b, MathOperation mathOperation){return mathOperation.operation(a, b);}interface MathOperation {int operation(int a, int b);}
}

编译结果:

2、target选项

参考官方文档

-target release
Generates class files for a specific VM version.

生成特定VM(虚拟机)版本的类文件。 默认值和JDK版本一致。

例如,我的JDK版本是1.8,我的程序没有使用Java SE 8的语言特性(假如使用了Java SE 7的特性),我们公司的系统使用的是JDK 7的虚拟机,我希望编译后的Class文件可以在JDK 7的虚拟机上运行,这是我编译文件时需要指定参数-target 7,当然根据虚拟机的兼容性,在高于target指定版本的虚拟机上都可以运行该Class文件。

Class文件是有版本的,有主版本号和次版本号,例如45.1,主版本号45,次版本号1

JDK 1.1的虚拟机可以运行的Class文件版本45.0~45.65535
JDK 1.2 45~46.65535
JDK 1.3 45~47.65535

JDK 1.7 45~51.65535
JDK 1.8 45~52.65535

Class文件的版本等于JDK版本 减去 1 再加上45。因为JDK1.1的Class文件版本是45.0;

注意,即使我只使用了Java SE 7的语言特性,但是我使用JDK 1.8的编译器, 没有指定target参数(相当于使用了默认值-target 1.8),导致我编译的Class文件的主版本为52,然而JDK 1.7的虚拟机最大只能支持主版本号51的Class文件。

代码如下:

import java.util.ArrayList;public class GenericTest {public static void main(String[] args) {ArrayList<String> words = new ArrayList<>();words.add("abandon");}
}

使用JDK 1.8的编译器进行编译,查看编译的Class文件的主版本号:

使用JDK 1.7的虚拟机运行该Class文件,发生错误。

总结:target选项,生成特定VM(虚拟机)版本的类文件。也就是说指定Class文件的版本,由于Class文件和虚拟机版本存在联系,也可以说指定了Class文件可以运行的虚拟机版本。

这两个参数我们平时并不经常用到,因为它主要用户交叉编译,就是说我们的项目由很多个模块组成,开发使用的JDK版本可能并不一致,还要考虑Class文件运行的虚拟机的问题,所以各个模块的source和target可能并不相同。

我们平时学习时,为了出现不必要的错误,将source和target配置为和JDK版本一致即可。

二、应用

以为JDK 1.8为例

1.Maven

pom.xml文件

  <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties>

2. IDEA

全局配置

模块配置,不同模块可以有不同配置,用于交叉编译。交叉编译以后用到会补充。

Javac选项source和target的作用相关推荐

  1. [ShapeInferenceError] Mismatch between number of source and target dimensions. Source=1 Target=0

    Pytorch转ONNX模型正常,但使用onnxruntime加载onnx模型,会输出错误: onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ON ...

  2. Could not copy property 'intro' from source to target; nested exception is java.lang.reflect.Invocat

    在使用BeanUtil copyProperties时,对两个不同的对象,但是大部分字段相同的对象进行复制时,出现了上面的错误,里面还有一些ClassCastException之类的. 但是复制失败的 ...

  3. Attention Focusing for Neural Machine Translation by Bridging Source and Target Embeddings 论文总结

    Attention Focusing for Neural Machine Translation by Bridging Source and Target Embeddings 论文总结 该文是阅 ...

  4. apk私钥_使用source/build/target/product/security/中的密钥将apk签署为系统

    正如标题所述,我试图使用platform.x509.pem和platform.pk8签署我的应用程序.问题是,当使用keytool-importkeypairs来添加这些内容时会出现错误: keyto ...

  5. 使用 Eclipse 建立包的时候,“name”下可选项“Create package-info.java”的作用是什么?

    一.场景描述 我们在使用 Eclipse 开发项目建包的时候,你是否发现在"name"下有可选项"Create package-info.java",除了根据英 ...

  6. Java编译器调试不了_使用Maven设置Java编译器的-source和-target-不起作用

    我已经设置了pom文件,要求Maven使用sourceand targetconfig参数将我的源代码编译为1.5版兼容.这是我的pom: 4.0.0 com user 0.0.1-SNAPSHOT ...

  7. leetcode 797. All Paths From Source to Target | 797. 所有可能的路径(回溯法)

    题目 https://leetcode.com/problems/all-paths-from-source-to-target/ 题解 回溯,中规中矩,直接上代码. class Solution { ...

  8. Centos7-Linux

    Centos7-Linux-RH Linux操作系统(百度百科):全称GNU/Linux,是一套免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年第一次释出,它主要 ...

  9. Linux笔记 No.17---(磁盘分区fdisk,gdisk,parted、格式化mkfs,mke2fs、挂载mount、卸载umount、df、du、lsof命令)

    文章目录 一.磁盘 (一)机械硬盘(HDD) 1.基本组成 2.逻辑结构 (二)固态硬盘(SSD) 二.硬盘分区 (一)基本概念 1. MBR(MS-DOS 主引导记录区)方案 2.GPT(GUID ...

  10. jdk 1.8 字符串+_JDK 9/10/11:Java字符串上+ =的副作用

    jdk 1.8 字符串+ 问题" 为什么`array [i ++%n] + = i +"在Java 8和Java 10中给出不同的结果? "已于本周初发布在StackOv ...

最新文章

  1. ads1115寄存器操作
  2. C 语言编程 — 宏定义与预处理器指令
  3. 物理服务器转虚拟服务器,物理服务器转虚拟服务器
  4. java antd实现登录,基于 antd pro 的短信验证码登录
  5. wait/notify的基本使用
  6. Linux 系统管理员工具集
  7. c#如何跨线程调用窗体控件
  8. 基于线性调频(LFM)信号分数阶傅里叶变换的多径时延估计
  9. java canvas 画图片_canvas画布——画八卦图
  10. 私有镜像仓库的部署与使用方法
  11. Android 系统(43)---HTTPS
  12. 三维点云学习(3)7- 实现GMM
  13. Django 视图与网址
  14. prototype中文参数乱码解决方案
  15. 计算机c盘如何扩大,C盘太小怎么办?教你扩大容量!
  16. 女研究生做“思维导图”与男友吵架!网友:吵架届的“内卷之王”....
  17. java增大字體_往JRE里增加字体
  18. 嵌入式linux编程开发必备知识
  19. 乐优商城遇到的坑一步一步总结
  20. python命令行调试_Linux 黑乎乎的命令行下,如何调试 Python?

热门文章

  1. 华为设备无线环境中的Portal认证
  2. PPT——背景图格式(排版)和字体排版
  3. 吴翰清​(道哥)眼中的机器智能:计算机的再发展
  4. 手把手教使用阿里云短信接口发送短信验证码
  5. B站4K视频下载方法
  6. postman实现接口请求
  7. IntelliJ IDEA 2020 提示“Unmapped Spring configuration files found.Please configure Spring facet.”解决办法
  8. python selenium自动化填写问卷星
  9. 云知声-AI离线语音识别芯片模块系列方案介绍
  10. 比特大陆将任命新任首席执行官