Cờ --release trong trình biên dịch Java 9 là gì?


85

Java 9 javaccó một cờ mới --release:

> javac --help
...

--release <release>
    Compile for a specific VM version. Supported targets: 6, 7, 8, 9

Nó khác với -source-targetcờ như thế nào? Nó chỉ là một phím tắt cho -source X -target X?


Câu trả lời:


106

Không chính xác.

JEP 247: Biên dịch cho phiên bản nền tảng cũ hơn định nghĩa tùy chọn dòng lệnh mới này,--release:

Chúng tôi đã xác định một tùy chọn dòng lệnh mới, tùy chọn --releasenày tự động cấu hình trình biên dịch để tạo ra các tệp lớp sẽ liên kết với việc triển khai phiên bản nền tảng nhất định. Đối với các nền tảng được xác định trước javac, --release Ntương đương với-source N -target N -bootclasspath <bootclasspath-from-N> . (nhấn mạnh của tôi)

Vì vậy, không, nó không tương đương với -source N -target N. Lý do cho sự bổ sung này được nêu trong phần "Động lực":

javaccung cấp hai tùy chọn dòng lệnh -source-targetcó thể được sử dụng để chọn phiên bản của ngôn ngữ Java được trình biên dịch chấp nhận và phiên bản của các tệp lớp mà nó tạo ra tương ứng. Tuy nhiên, theo mặc định, javacbiên dịch dựa trên phiên bản mới nhất của các API nền tảng. Do đó, chương trình đã biên dịch có thể vô tình sử dụng các API chỉ có sẵn trong phiên bản hiện tại của nền tảng. Các chương trình như vậy không thể chạy trên các phiên bản cũ hơn của nền tảng, bất kể các giá trị được chuyển đến -source-target. các tùy chọn. Đây là điểm khó khăn về khả năng sử dụng lâu dài, vì người dùng mong đợi rằng bằng cách sử dụng các tùy chọn này, họ sẽ nhận được các tệp lớp có thể chạy trên phiên bản nền tảng được chỉ định.

Tóm lại, việc chỉ định các tùy chọn nguồn và đích là không đủ để biên dịch chéo. Bởi vì javac, theo mặc định, biên dịch dựa trên API nền tảng mới nhất, nên chúng không thể được đảm bảo chạy trên các phiên bản cũ hơn. Bạn cũng cần chỉ định -bootclasspathtùy chọn tương ứng với phiên bản cũ hơn để biên dịch chéo một cách chính xác. Điều này sẽ bao gồm phiên bản API chính xác để biên dịch và cho phép thực thi trên phiên bản cũ hơn. Vì nó rất hay bị quên, nên người ta quyết định thêm một tùy chọn dòng lệnh thực hiện tất cả những điều cần thiết để biên dịch chéo một cách chính xác.

Đọc thêm trong danh sách gửi thưTài liệu Oracle . Lỗi ban đầu đã được nộp ở đây . Lưu ý rằng kể từ khi tích hợp tùy chọn này, các bản dựng JDK đã đi kèm với mô tả về các API nền tảng của các bản phát hành cũ hơn, được đề cập trong phần "Rủi ro và giả định". Điều đó có nghĩa là bạn không cần cài đặt phiên bản cũ hơn trên máy của mình để quá trình biên dịch chéo hoạt động.


một nghi ngờ, liệu có thể sử dụng các tính năng từ jdk 9-11 trong mã và nó vẫn chạy trên java runtime 8 không?
Cristiano

Không, chúng sẽ không có mặt trong hệ nhị phân jre 8
Rogue

Bạn đàn ông bằng "API nền tảng" là gì? Có thứ gì đó ở cấp mã byte không? hoặc thứ gì đó liên quan đến nền tảng x86 hoặc API hệ điều hành bên dưới?
Jose Cifuentes

2
@JoseCifuentes, "API nền tảng" ở đây được cấp cho API JDK phiên bản của nó, không có --releasecờ, sẽ được suy ra từ JDK được sử dụng để biên dịch, thường khác với JDK mà bạn nhắm mục tiêu sử dụng -source-target. Điều này có thể khiến bạn khó chịu trong trường hợp bạn tình cờ sử dụng các lớp / phương thức được giới thiệu trong không bao giờ JDK sau đó là lớp bạn nhắm mục tiêu. Điều này cực kỳ tinh vi trong trường hợp trình biên dịch chọn quá tải phương thức đã được thêm vào trong phiên bản mới hơn so với phiên bản trước mà bạn dự định, do đó âm thầm phá vỡ khả năng tương thích nhị phân.
Oliver Gondža

30

--release Xkhông chỉ là một lối tắt đến -source X -target X-source-targetkhông đủ để biên dịch một cách an toàn sang phiên bản cũ hơn. Bạn cũng cần đặt -bootclasspathcờ phải tương ứng với phiên bản cũ hơn (và cờ này thường bị quên). Vì vậy, trong Java 9 họ đã làm cho một đơn --releasecờ mà là một sự thay thế cho ba lá cờ: -source, -target-bootclasspath.

Vì vậy, đây là một ví dụ về biên dịch sang Java 1.7:

javac --release 7 <source files>

Lưu ý rằng bạn thậm chí không cần phải cài đặt JDK 7 trên máy tính của mình. JDK 9 đã chứa thông tin cần thiết để ngăn bạn vô tình liên kết đến các ký hiệu không tồn tại trong JDK 7.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.