IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Javac选项source和target的作用 -> 正文阅读

[Java知识库]Javac选项source和target的作用

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

一 .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);
    }
}


编译结果:
在这里插入图片描述

二、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

全局配置
在这里插入图片描述
模块配置,不同模块可以有不同配置,用于交叉编译。交叉编译以后用到会补充。
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:27:33  更:2022-04-18 17:29:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:55:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码