| JAVAC(1) | JDK Commands | JAVAC(1) |
نام (NAME)
javac - خواندن اعلانهای جاوا و کامپایل آنها به فایلهای کلاس
خلاصه دستور (SYNOPSIS)
javac [options] [sourcefiles-or-classnames]
- options
- گزینههای خط فرمان.
- sourcefiles-or-classnames
- فایلهای مبدأ برای کامپایل (برای نمونه، Shape.java) یا نام کلاسهای قبلاً کامپایلشده جهت پردازش حاشیهنویسیها (برای نمونه، geometry.MyShape).
توضیحات (DESCRIPTION)
دستور javac فایلهای مبدأ حاوی اعلانهای ماژول، پکیج و نوعِ نوشتهشده به زبان برنامهنویسی Java را میخواند و آنها را به فایلهای کلاس کامپایل میکند تا روی ماشین مجازی جاوا (JVM) اجرا شوند.
دستور javac همچنین میتواند حاشیهنویسیها (annotations) را در فایلهای مبدأ و کلاسهای جاوا پردازش کند.
فایلهای مبدأ باید پسوند نام فایل .java داشته باشند. فایلهای کلاس پسوند نام فایل .class دارند. معمولاً هر دو فایلهای مبدأ و کلاس دارای نامهایی هستند که محتوای آنها را مشخص میسازد. برای نمونه، کلاسی به نام Shape در فایل مبدأیی به نام Shape.java اعلان میشود و در یک فایل کلاس به نام Shape.class کامپایل خواهد شد.
دو روش برای مشخص کردن فایلهای مبدأ به javac وجود دارد:
- •
- برای تعداد کمی از فایلهای مبدأ، میتوانید نام آنها را در خط فرمان درج کنید.
- •
- برای تعداد زیادی از فایلهای مبدأ، میتوانید از گزینهٔ @filename در خط فرمان برای تعیین یک فایل آرگومان استفاده کنید که نام آن فایلها در آن فهرست شده است. برای شرح این گزینه به بخش گزینههای استاندارد (Standard Options) و برای شرح فایلهای آرگومان javac به فایلهای آرگومان خط فرمان (Command-Line Argument Files) مراجعه نمایید.
ترتیب فایلهای مبدأ مشخصشده در خط فرمان یا در یک فایل آرگومان اهمیتی ندارد. javac فایلها را با هم و به صورت گروهی کامپایل میکند و وابستگیهای میان اعلانها در فایلهای مبدأ گوناگون را بهطور خودکار برطرف میسازد.
javac انتظار دارد که فایلهای مبدأ در یک یا چند ساختار سلسلهمراتبی دایرکتوری در سیستم فایل چیده شده باشند، همانگونه که در چیدمان کد مبدأ (Arrangement of Source Code) شرح داده شده است.
برای کامپایل یک فایل مبدأ، javac باید اعلان هر کلاس یا رابطی (اینترفیسی) را که توسط کد موجود در فایل مبدأ استفاده شده، گسترش یافته (extended) یا پیادهسازی شده (implemented) است پیدا کند. این کار به javac امکان میدهد بررسی کند که آیا کد، حق دسترسی به آن کلاسها و رابطها را دارد یا خیر. به جای مشخص کردن مستقیم فایلهای مبدأ آن کلاسها و رابطها، میتوانید از گزینههای خط فرمان استفاده کنید تا به javac اعلام کنید کجا به دنبال فایلهای مبدأ آنها بگردد. اگر آن فایلهای مبدأ را قبلاً کامپایل کردهاید، میتوانید از گزینهها استفاده کنید تا به javac بگویید کجا به دنبال فایلهای کلاس متناظر جستجو کند. این گزینهها که همگی نامهایی ختمشده به "path" دارند، در بخش گزینههای استاندارد (Standard Options) شرح داده شدهاند و توضیحات بیشتر دربارهٔ آنها در پیکربندی کامپایل (Configuring a Compilation) و جستجوی اعلانهای ماژول، پکیج و نوع (Searching for Module, Package and Type Declarations) آمده است.
بهطور پیشفرض، javac هر فایل مبدأ را به یک فایل کلاس در همان دایرکتوری فایل مبدأ کامپایل میکند. با این حال، توصیه میشود یک دایرکتوری مقصد مجزا با استفاده از گزینهٔ -d تعیین شود.
گزینهها و متغیرهای محیطی خط فرمان نیز نحوهٔ انجام وظایف گوناگون توسط javac را کنترل میکنند:
- •
- کامپایل کد جهت اجرا روی نگارشهای پیشین JDK.
- •
- کامپایل کد جهت اجرا تحت یک دیباگر.
- •
- بررسی ایرادات سبکی و نگارشی در کد مبدأ جاوا.
- •
- بررسی اشکالات موجود در یادداشتهای javadoc (/** ... */).
- •
- پردازش حاشیهنویسیها در فایلهای مبدأ و فایلهای کلاس.
- •
- ارتقا و وصله کردن ماژولها در محیط زمان کامپایل.
دستور javac از کامپایل برای نگارشهای قبلی پلتفرم (Compiling for Earlier Releases Of The Platform) پشتیبانی میکند و همچنین میتواند از داخل کد جاوا با بهرهگیری از شماری از APIها فراخوانی شود..SH "گزینهها (OPTIONS)"
دستور javac گزینههای استاندارد و همچنین گزینههای اضافی را که غیراستاندارد بوده یا برای استفاده پیشرفته هستند، ارائه میدهد.
برخی گزینهها یک یا چند آرگومان دریافت میکنند. اگر یک آرگومان حاوی فاصله یا دیگر نویسههای فاصلهساز باشد، مقدار آن باید مطابق با قواعد محیطی که برای فراخوانی javac به کار میرود، درون علامت نقلقول قرار گیرد. اگر گزینه با یک خط تیره منفرد (-) آغاز شود، آرگومان باید بسته به نوع گزینه، یا بلافاصله پس از نام گزینه بیاید، یا با یک دونقطه (:) یا فاصله سفید جدا شود. اگر گزینه با دو خط تیره (--) آغاز شود، آرگومان میتواند با فاصله سفید یا با نویسه مساوی (=) بدون هیچگونه فاصله سفید اضافی جدا شود. برای مثال،
-
-Aname="J. Duke" -proc:only -d myDirectory --module-version 3 --module-version=3
در فهرستهای گزینههای زیر، آرگومان path نشاندهنده یک مسیر جستوجو است که از فهرستی از مکانهای سیستمفایل تشکیل شده و با نویسه جداکننده مسیر پلتفرم (نقطهویرگول ; در Windows، یا دونقطه : در سایر سیستمها) از هم جدا میشوند. بسته به گزینه، مکانهای سیستمفایل میتوانند دایرکتوریها، فایلهای JAR یا فایلهای JMOD باشند.
گزینههای استاندارد (Standard Options)
- @filename
- گزینهها و نامهای فایل را از یک فایل میخواند. برای کوتاهتر کردن یا سادهسازی دستور javac، میتوانید یک یا چند فایل حاوی آرگومانهای دستور javac (بهجز گزینههای -J) را مشخص کنید. این کار به شما امکان میدهد دستورهای javac با هر طولی را روی هر سیستمعاملی ایجاد کنید. بخش Command-Line Argument Files را ببینید.
- -Akey[=value]
- گزینههایی را برای ارسال به پردازندههای حاشیهنویسی (annotation processors) مشخص میکند. این گزینهها مستقیماً توسط javac تفسیر نمیشوند، بلکه در دسترس پردازندهها قرار میگیرند. مقدار key باید یک یا چند شناسه باشد که با نقطه (.) از هم جدا شدهاند.
- --add-modules module,module
- ماژولهای ریشه را علاوه بر ماژولهای اولیه برای تفکیک (resolve) مشخص میکند، یا در صورتی که module برابر با ALL-MODULE-PATH باشد، تمام ماژولهای موجود در مسیر ماژول را تعیین میکند.
- --boot-class-path path یا -bootclasspath path
- مکان فایلهای کلاس راهاندازی (bootstrap class files) را جایگزین میکند.
نکته: این گزینه تنها هنگام کامپایل برای نسخههای پیش از JDK 9 قابل استفاده است. در صورت لزوم، برای جزئیات به توضیحات موجود در --release، -source یا -target مراجعه کنید. برای JDK 9 یا جدیدتر، به --system مراجعه کنید.
- --class-path path، -classpath path، یا -cp path
- مکان یافتن فایلهای کلاس کاربری و پردازندههای حاشیهنویسی را مشخص میکند. این مسیر کلاس، مقدار مسیر کلاس کاربر را در متغیر محیطی CLASSPATH بازنویسی و لغو میکند.
- •
- اگر --class-path، -classpath یا -cp مشخص نشده باشند، مسیر کلاس کاربر برابر با مقدار متغیر محیطی CLASSPATH (در صورت مقداردهی) یا دایرکتوری جاری خواهد بود.
- •
- در صورت عدم کامپایل کد برای ماژولها، اگر گزینه --source-path یا -sourcepath` مشخص نشده باشد، مسیر کلاس کاربر برای فایلهای مبدأ نیز جستوجو میشود.
- •
- اگر گزینه -processorpath مشخص نشده باشد، مسیر کلاس برای پردازندههای حاشیهنویسی نیز جستوجو میشود.
- -d directory
- دایرکتوری مقصد (یا دایرکتوری خروجی کلاس) را برای فایلهای کلاس تعیین میکند. اگر کلاسی بخشی از یک بسته باشد، javac فایل کلاس را در زیردایرکتوریای قرار میدهد که منعکسکننده نام ماژول (در صورت کاربرد) و نام بسته است. دایرکتوری و زیردایرکتوریهای لازم در صورت عدم وجود، ایجاد خواهند شد.
اگر گزینه -d مشخص نشده باشد، javac هر فایل کلاس را در همان دایرکتوری فایل مبدأ سازنده آن قرار میدهد.
بهجز هنگام کامپایل کد برای چندین ماژول، محتویات دایرکتوری خروجی کلاس بر اساس سلسلهمراتب بستهها سازماندهی خواهد شد. هنگام کامپایل کد برای چندین ماژول، محتویات دایرکتوری خروجی در یک سلسلهمراتب ماژول سازماندهی میشود، بهطوری که محتویات هر ماژول در یک زیردایرکتوری جداگانه و بر اساس سلسلهمراتب بسته مربوط به خود مرتب میشود.
نکته: هنگام کامپایل کد برای یک یا چند ماژول، دایرکتوری خروجی کلاس بهطور خودکار هنگام جستوجو برای کلاسهای از پیش کامپایلشده بررسی میشود. هنگامی که کامپایل برای ماژولها انجام نمیشود، برای حفظ سازگاری با گذشته، دایرکتوری بهطور خودکار برای کلاسهای کامپایلشده پیشین بررسی نمیشود؛ بنابراین توصیه میشود دایرکتوری خروجی کلاس را با استفاده از گزینه --class-path یا یکی از شکلهای جایگزین آن، بهعنوان یکی از مکانهای موجود در مسیر کلاس کاربر مشخص کنید.
- -deprecation
- توضیحاتی از هر مورد استفاده یا بازنویسی (override) یک عضو یا کلاس منسوخشده را نمایش میدهد. بدون گزینه -deprecation، دستور javac خلاصهای از فایلهای مبدأ را که از اعضا یا کلاسهای منسوخشده استفاده کرده یا آنها را بازنویسی نمودهاند نشان میدهد. گزینه -deprecation مخفف -Xlint:deprecation است.
- --enable-preview
- ویژگیهای پیشنمایش زبان را فعال میکند. بههمراه یکی از گزینههای -source یا --release به کار میرود.
- -encoding encoding
- کدگذاری نویسه مورد استفاده در فایلهای مبدأ مانند EUC-JP و UTF-8 را مشخص میکند. اگر گزینه -encoding مشخص نشده باشد، از مبدل پیشفرض پلتفرم استفاده میشود.
- -endorseddirs directories
- مکان مسیر استانداردهای تأییدشده (endorsed standards path) را جایگزین میکند.
نکته: این گزینه فقط هنگام کامپایل برای نسخههای پیش از JDK 9 قابل استفاده است. در صورت لزوم، برای جزئیات به توضیحات --release، -source یا -target مراجعه کنید.
- -extdirs directories
- مکان افزونههای نصبشده را جایگزین میکند. directories فهرستی از دایرکتوریها است که با جداکننده مسیر پلتفرم (نقطهویرگول ; در Windows، و دونقطه : در سایر سیستمها) جدا شدهاند. تمامی فایلهای JAR موجود در دایرکتوریهای مشخصشده برای یافتن فایلهای کلاس جستوجو میشوند. تمامی فایلهای JAR یافتشده بخشی از مسیر کلاس خواهند شد.
اگر برای نسخهای از پلتفرم کامپایل میکنید که از سازوکار افزونه (Extension Mechanism) پشتیبانی میکند، این گزینه دایرکتوریهای حاوی کلاسهای افزونه را مشخص میکند. بخش [Compiling for Other Releases of the Platform] را ببینید.
نکته: این گزینه فقط هنگام کامپایل برای نسخههای پیش از JDK 9 قابل استفاده است. در صورت لزوم، برای جزئیات به توضیحات --release، -source یا -target مراجعه کنید.
- -g
- تمام اطلاعات اشکالزدایی، از جمله متغیرهای محلی را تولید میکند. بهطور پیشفرض، فقط اطلاعات شماره خط و فایل مبدأ تولید میشود.
- -g:[lines, vars, source]
- تنها انواع اطلاعات اشکالزدایی مشخصشده توسط فهرست کلیدواژههای جداشده با کاما را تولید میکند. کلیدواژههای معتبر عبارتند از:
- lines
- اطلاعات اشکالزدایی شماره خط..TP vars اطلاعات اشکالزدایی متغیرهای محلی.
- source
- اطلاعات اشکالزدایی پروندهٔ منبع.
- -g:none
- اطلاعات اشکالزدایی را تولید نمیکند.
- -h directory
- محل قرارگیری پروندههای سرآیند بومی (native header) تولیدشده را مشخص میکند.
هنگامی که این گزینه را مشخص میکنید، برای هر کلاسی که شامل متدهای بومی است یا دارای یک یا چند ثابت است که با حاشیهنویسی java.lang.annotation.Native نشانهگذاری شدهاند، یک پروندهٔ سرآیند بومی تولید میشود. اگر کلاس بخشی از یک بسته باشد، کامپایلر پروندهٔ سرآیند بومی را در یک زیرپوشه متناسب با نام پودمان (در صورت لزوم) و نام بسته قرار میدهد. اگر پوشه و زیرپوشههای لازم از پیش موجود نباشند، ایجاد خواهند شد.
- --help، -help یا -?
- خلاصهای از گزینههای استاندارد را چاپ میکند.
- --help-extra یا -X
- خلاصهای از مجموعه گزینههای اضافی را چاپ میکند.
- --help-lint
- کلیدهای پشتیبانیشده برای گزینهٔ -Xlint را چاپ میکند.
- -implicit:[none, class]
- مشخص میکند که آیا برای پروندههای دارای ارجاع ضمنی، پروندههای کلاس تولید شوند یا خیر:
- •
- -implicit:class --- بهطور خودکار پروندههای کلاس را تولید میکند.
- •
- -implicit:none --- از تولید پروندههای کلاس جلوگیری میکند.
اگر این گزینه مشخص نشود، رفتار پیشفرض تولید خودکار پروندههای کلاس است. در این حالت، در صورت تولید هرگونه پروندهٔ کلاس در حین پردازش حاشیهنویسی، کامپایلر یک هشدار صادر میکند. هنگامی که گزینهٔ -implicit بهطور صریح تنظیم شده باشد، این هشدار صادر نمیشود. بخش Searching for Module, Package and Type Declarations را ببینید.
- -Joption
- گزینهٔ option را به سیستم زماناجرا ارسال میکند، که در آن option یکی از گزینههای جاوای شرحدادهشده در دستور java است. برای نمونه، -J-Xms48m مقدار حافظهٔ راهاندازی را روی ۴۸ مگابایت تنظیم میکند.
نکته: متغیر محیطی CLASSPATH، گزینهٔ -classpath، گزینهٔ -bootclasspath و گزینهٔ -extdirs کلاسهای مورد استفاده برای اجرای javac را مشخص نمیکنند. تلاش برای سفارشیسازی پیادهسازی کامپایلر با این گزینهها و متغیرها پرخطر است و اغلب به نتیجهٔ مورد نظر شما منجر نمیشود. اگر حتماً باید پیادهسازی کامپایلر را سفارشی کنید، از گزینهٔ -J برای ارسال گزینهها به راهانداز زیرین جاوا استفاده کنید.
- --limit-modules module,module*
- محدودهٔ پودمانهای قابلمشاهده را محدود میکند.
- --module module-name (,module-name)* یا -m module-name (,module-name)*
- آن دسته از پروندههای منبع در پودمانهای نامبرده را که جدیدتر از پروندههای متناظر در پوشهٔ خروجی هستند، کامپایل میکند.
- --module-path path یا -p path
- محل یافتن پودمانهای برنامه کاربردی را مشخص میکند.
- --module-source-path module-source-path
- محل یافتن پروندههای منبع را هنگام کامپایل کد در چند پودمان مشخص میکند. بخشهای [Compilation Modes] و The Module Source Path Option را ببینید.
- --module-version version
- نسخهٔ پودمانهای در حال کامپایل را مشخص میکند.
- -nowarn
- پیامهای هشدار را غیرفعال میکند. عملکرد این گزینه مشابه گزینهٔ -Xlint:none است.
- -parameters
- فرادهاده را برای بازتاب (reflection) روی پارامترهای متد تولید میکند. نامهای صوری پارامترهای سازندهها و متدها را در پروندهٔ کلاسِ تولیدشده ذخیره میکند تا متد java.lang.reflect.Executable.getParameters از API بازتاب بتواند آنها را بازیابی کند.
- -proc:[none, only, full]
- انجام پردازش حاشیهنویسی و کامپایل را کنترل میکند. مقدار -proc:none به این معنی است که کامپایل بدون پردازش حاشیهنویسی انجام میشود. مقدار -proc:only به این معنی است که تنها پردازش حاشیهنویسی انجام میشود، بدون اینکه کامپایل بعدی صورت گیرد. اگر از این گزینه استفاده نشود، یا -proc:full مشخص شده باشد، پردازش حاشیهنویسی و کامپایل هر دو انجام میشوند.
- -processor class1[,class2,class3...]
- نامهای پردازندههای حاشیهنویسی برای اجرا. این کار فرایند پیشفرض اکتشاف (discovery) را دور میزند.
- --processor-module-path path
- مسیر پودمانی مورد استفاده برای یافتن پردازندههای حاشیهنویسی را مشخص میکند.
- --processor-path path یا -processorpath path
- محل یافتن پردازندههای حاشیهنویسی را مشخص میکند. اگر از این گزینه استفاده نشود، مسیر کلاس (class path) برای یافتن پردازندهها جستجو میشود.
- -profile profile
- بررسی میکند که آیا API استفادهشده در نمایهٔ (profile) مشخصشده موجود است یا خیر. این گزینه منسوخ شده است و ممکن است در نگارشهای آینده حذف شود.
نکته: این گزینه تنها هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. در صورت نیاز، برای جزئیات به توضیحات گزینههای --release، -source یا -target مراجعه کنید.
- --release release
- کد منبع را مطابق با قواعد زبان برنامهنویسی جاوا برای نگارش مشخصشدهٔ Java SE کامپایل میکند و پروندههای کلاسی را تولید میکند که آن نگارش را هدف قرار میدهند. کد منبع در برابر API ترکیبشدهٔ Java SE و JDK برای نگارش مشخصشده کامپایل میشود.
مقدارهای پشتیبانیشده برای release شامل نگارش کنونی Java SE و تعداد محدودی از نگارشهای پیشین است که جزئیات آن در راهنمای خط فرمان آمده است.
برای نگارش کنونی، Java SE API شامل بستههای java.*، javax.* و org.* است که توسط پودمانهای Java SE در آن نگارش صادر (export) شدهاند؛ JDK API شامل بستههای com.* و jdk.* است که توسط پودمانهای JDK در آن نگارش صادر شدهاند، به همراه بستههای javax.* که توسط پودمانهای استاندارد (اما غیر Java SE) در آن نگارش صادر شدهاند.
برای نگارشهای پیشین، Java SE API و JDK API همانگونه هستند که در آن نگارش تعریف شدهاند.
نکته: هنگام استفاده از --release، نمیتوانید همزمان از گزینههای --source/-source یا --target/-target استفاده کنید.
نکته: هنگام استفاده از --release برای مشخصکردن نگارشی که از سامانهٔ پودمان پلتفرم جاوا (Java Platform Module System) پشتیبانی میکند، گزینهٔ --add-exports نمیتواند برای گسترش مجموعه بستههای صادرشده توسط پودمانهای Java SE، JDK و پودمانهای استاندارد در نگارش مشخصشده استفاده شود.
- -s directory
- پوشهٔ مورد استفاده برای قرار دادن پروندههای منبع تولیدشده را مشخص میکند. اگر کلاسی بخشی از یک بسته باشد، کامپایلر پروندهٔ منبع را در یک زیرپوشه متناسب با نام پودمان (در صورت لزوم) و نام بسته قرار میدهد. اگر پوشه و هرگونه زیرپوشهٔ لازم از پیش موجود نباشند، ایجاد خواهند شد.
به جز در هنگام کامپایل کد برای چند پودمان، محتویات پوشهٔ خروجی منبع در یک سلسلهمراتب بستهای سازماندهی خواهند شد. هنگام کامپایل کد برای چند پودمان، محتویات پوشهٔ خروجی منبع در یک سلسلهمراتب پودمانی سازماندهی خواهند شد، بهطوری که محتویات هر پودمان در یک زیرپوشهٔ جداگانه قرار گرفته و هر یک به صورت یک سلسلهمراتب بستهای سازماندهی میشوند. --source release یا -source release کد منبع را بر اساس قوانین زبان برنامهنویسی Java برای نگارش (release) مشخصشدهٔ Java SE کامپایل میکند. مقادیر پشتیبانیشده برای release نگارش فعلی Java SE و تعداد محدودی از نگارشهای پیشین هستند که جزئیات آنها در راهنمای خط فرمان آمده است.
اگر این گزینه مشخص نشود، مقدار پیشفرض کامپایل کردن کد منبع بر اساس قوانین زبان برنامهنویسی Java برای نگارش فعلی Java SE است.
- --source-path path یا -sourcepath path
- محل یافتن فایلهای منبع را مشخص میکند. به جز در زمان کامپایل چندین ماژول با یکدیگر، این مسیر کد منبع است که برای جستجوی تعاریف کلاس یا واسط (interface) استفاده میشود.
نکته: کلاسهای یافتشده از طریق مسیر کلاس (class path) ممکن است در صورت پیدا شدن فایلهای منبع آنها، مجدداً کامپایل شوند. بخش Searching for Module, Package and Type Declarations را ببینید.
- --system jdk | none
- مکان ماژولهای سیستمی را جایگزین میکند.
- --target release یا -target release
- فایلهای class مناسب برای نگارش مشخصشدهٔ Java SE تولید میکند. مقادیر پشتیبانیشده برای release نگارش فعلی Java SE و تعداد محدودی از نگارشهای پیشین هستند که جزئیات آنها در راهنمای خط فرمان آمده است.
نکته: نگارش هدف باید مساوی یا بالاتر از نگارش منبع باشد. (--source را ببینید.)
- --upgrade-module-path path
- مکان ماژولهای ارتقاپذیر را جایگزین میکند.
- -verbose
- پیامهایی دربارهٔ عملکرد کامپایلر در خروجی نمایش میدهد. پیامها شامل اطلاعاتی دربارهٔ هر کلاس بارگذاریشده و هر فایل منبع کامپایلشده است.
- --version یا -version
- اطلاعات نگارش را نمایش میدهد.
- -Werror
- در صورت بروز هشدار، فرآیند کامپایل را متوقف میکند.
گزینههای اضافی (Extra Options)
- --add-exports module/package=other-module(,other-module)*
- بستهای را مشخص میکند تا طوری در نظر گرفته شود که از ماژول تعریفکنندهاش به ماژولهای دیگر، یا در صورتی که مقدار other-module برابر با ALL-UNNAMED باشد به تمام ماژولهای بینام، صادر (export) شده است.
- --add-reads module=other-module(,other-module)*
- ماژولهای اضافی را مشخص میکند تا به عنوان نیازمندیهای یک ماژول دادهشده در نظر گرفته شوند.
- --default-module-for-created-files module-name
- ماژول هدف پیشفرض (fallback) را برای فایلهای ایجادشده توسط پردازشگرهای حاشیهنویسی (annotation processors)، در صورتی که هیچ ماژولی مشخص یا استنباط نشده باشد، تعیین میکند.
- -Djava.endorsed.dirs=dirs
- مکان مسیر استانداردهای تأییدشده (endorsed standards) را جایگزین میکند.
نکته: این گزینه فقط هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. برای جزئیات بیشتر، بر حسب مورد، توضیحات موجود در --release، -source یا -target را ببینید.
- -Djava.ext.dirs=dirs
- مکان افزونههای نصبشده را جایگزین میکند.
نکته: این گزینه فقط هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. برای جزئیات بیشتر، بر حسب مورد، توضیحات موجود در --release، -source یا -target را ببینید.
- --patch-module module=path
- یک ماژول را با کلاسها و منابع موجود در فایلهای JAR یا دایرکتوریها بازنویسی یا گسترش میدهد.
- -Xbootclasspath:path
- مکان فایلهای کلاس راهانداز (bootstrap) را جایگزین میکند.
نکته: این گزینه فقط هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. برای جزئیات بیشتر، بر حسب مورد، توضیحات موجود در --release، -source یا -target را ببینید.
- -Xbootclasspath/a:path
- یک پسوند به مسیر کلاسهای راهانداز اضافه میکند.
نکته: این گزینه فقط هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. برای جزئیات بیشتر، بر حسب مورد، توضیحات موجود در --release، -source یا -target را ببینید.
- -Xbootclasspath/p:path
- یک پیشوند به مسیر کلاسهای راهانداز اضافه میکند.
نکته: این گزینه فقط هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. برای جزئیات بیشتر، بر حسب مورد، توضیحات موجود در --release، -source یا -target را ببینید.
- -Xdiags:[compact, verbose]
- یک حالت عیبیابی را انتخاب میکند.
- -Xdoclint
- بررسیهای توصیهشده برای مشکلات موجود در کامنتهای مستندسازی را فعال میکند.
- -Xdoclint:(all|none|[-]group)[/access]
- گروههای خاصی از بررسیها در کامنتهای مستندسازی را فعال یا غیرفعال میکند.
متغیر group میتواند یکی از مقادیر زیر را داشته باشد: accessibility، html، missing، reference، syntax.
متغیر access حداقل سطح دید (visibility) کلاسها و اعضایی را که گزینهٔ -Xdoclint بررسی میکند، مشخص مینماید. این متغیر میتواند یکی از مقادیر زیر را داشته باشد (به ترتیب از بیشترین به کمترین میزان دید): public، protected، package، private.
سطح دید پیشفرض access برابر با private است.
هنگامی که پیشوند doclint: اعمال شود، نامهای group و all را میتوان همراه با @SuppressWarnings برای نادیده گرفتن هشدارهای مربوط به کامنتهای مستندسازی در بخشهایی از کد کامپایلشونده استفاده کرد.
برای اطلاعات بیشتر دربارهٔ این گروههای بررسی، بخش DocLint از مستندات دستور javadoc را ببینید. گزینهٔ -Xdoclint به صورت پیشفرض در دستور javac غیرفعال است.
برای مثال، گزینهٔ زیر کلاسها و اعضایی را (با تمام گروههای بررسی) بررسی میکند که سطح دسترسی protected و بالاتر دارند (شامل protected و public):
-Xdoclint:all/protected
گزینهٔ زیر تمام گروههای بررسی را برای همهٔ سطوح دسترسی فعال میکند، به جز اینکه خطاهای HTML را برای کلاسها و اعضایی که سطح دسترسی package و بالاتر دارند (شامل package، protected و public) بررسی نخواهد کرد:
-Xdoclint:all,-html/package
- -Xdoclint/package:[-]packages(,[-]package)*
- بررسیها را در بستههای مشخص فعال یا غیرفعال میکند. هر package یا نام کامل یک بسته است یا پیشوندی از نام بسته به همراه .*، که به تمام زیربستههای بستهٔ دادهشده گسترش مییابد. هر package میتواند یک پیشوند خط تیره (-) داشته باشد تا بررسیها برای بسته یا بستههای مشخصشده غیرفعال شوند. برای اطلاعات بیشتر، بخش DocLint از مستندات دستور javadoc را ببینید.
- -Xlint
- تمام هشدارهای توصیهشده را فعال میکند. در این نسخه، فعالسازی تمام هشدارهای موجود توصیه میشود.
- -Xlint:[-]key(,[-]key)*
- هشدارهایی را برای فعال یا غیرفعال کردن، به صورت جداشده با ویرگول تعیین میکند. برای غیرفعال کردن یک هشدار مشخص، پیش از کلید یک خط تیره (-) قرار دهید.
مقادیر پشتیبانیشده برای key عبارتند از:
- •
- all: تمام هشدارها را فعال میکند.
- •
- auxiliaryclass: درباره یک کلاس کمکی که در یک فایل مبدأ پنهان شده و از فایلهای دیگر استفاده میشود، هشدار میدهد.
- •
- cast: درباره استفاده از تبدیل نوعهای (cast) غیرضروری هشدار میدهد.
- •
- classfile: درباره مسائل مربوط به محتویات فایل کلاس (classfile) هشدار میدهد.
- •
- deprecation: درباره استفاده از موارد منسوخشده هشدار میدهد.
- •
- dep-ann: درباره مواردی که در javadoc به عنوان منسوخ علامتگذاری شدهاند اما فاقد یادداشت @Deprecated هستند، هشدار میدهد.
- •
- divzero: درباره تقسیم بر عدد صحیح ثابت 0 هشدار میدهد.
- •
- empty: درباره دستور خالی پس از if هشدار میدهد.
- •
- exports: درباره مسائل مربوط به صدورهای ماژول (module exports) هشدار میدهد.
- •
- fallthrough: درباره ریزش (fall-through) از یک حالت دستور switch به حالت بعدی هشدار میدهد.
- •
- finally: درباره بندهای finally که بهطور عادی خاتمه نمییابند هشدار میدهد.
- •
- lossy-conversions: درباره تبدیلهای همراه با اتلاف احتمالی در انتسابهای مرکب هشدار میدهد.
- •
- missing-explicit-ctor: درباره نبود سازندههای صریح در کلاسهای public و protected درون بستههای صادرشده هشدار میدهد.
- •
- module: درباره مسائل مربوط به سامانه ماژول هشدار میدهد.
- •
- opens: درباره مسائل مربوط به گشودنهای ماژول (module opens) هشدار میدهد.
- •
- options: درباره مسائل مربوط به استفاده از گزینههای خط فرمان هشدار میدهد.
- •
- output-file-clash: اگر فایلی در خروجی حین کامپایل بازنویسی شود، هشدار میدهد. این وضعیت مثلاً میتواند در سیستمهای فایلی که به بزرگی و کوچکی حروف حساس نیستند رخ دهد.
- •
- overloads: درباره مسائل مربوط به چندریختی یا سربارگذاری متدها (method overloads) هشدار میدهد.
- •
- overrides: درباره مسائل مربوط به بازنویسی متدها (method overrides) هشدار میدهد.
- •
- path: درباره عناصر مسیر نامعتبر در خط فرمان هشدار میدهد.
- •
- preview: درباره استفاده از ویژگیهای پیشنمایش زبان هشدار میدهد.
- •
- processing: درباره مسائل مربوط به پردازش یادداشتها (annotation processing) هشدار میدهد.
- •
- rawtypes: درباره استفاده از نوعهای خام (raw types) هشدار میدهد.
- •
- removal: درباره استفاده از یک API که برای حذف علامتگذاری شده است، هشدار میدهد.
- •
- requires-automatic: به توسعهدهندگان درباره استفاده از ماژولهای خودکار در بندهای requires هشدار میدهد.
- •
- requires-transitive-automatic: درباره ماژولهای خودکار در requires transitive هشدار میدهد.
- •
- serial: درباره کلاسهای سریالپذیر (serializable) که شناسه نسخه سریال (serial version ID) ارائه نمیدهند هشدار میدهد. همچنین درباره دسترسی به اعضای غیرعمومی از طریق یک عنصر سریالپذیر هشدار میدهد.
- •
- static: درباره دسترسی به یک عضو ایستا (static) با استفاده از یک نمونه هشدار میدهد.
- •
- strictfp: درباره استفاده غیرضروری از اصلاحگر strictfp هشدار میدهد.
- •
- synchronization: درباره تلاش برای همگامسازی روی نمونههایی از کلاسهای مبتنی بر مقدار هشدار میدهد.
- •
- text-blocks: درباره نویسههای فاصلهگذاری ناسازگار در تورفتگی بلوکهای متنی هشدار میدهد.
- •
- this-escape: درباره نشت this توسط سازندهها پیش از مقداردهی اولیه زیرکلاس هشدار میدهد.
- •
- try: درباره مسائل مربوط به استفاده از بلوکهای try (یعنی try-with-resources) هشدار میدهد.
- •
- unchecked: درباره عملیاتهای بررسینشده (unchecked) هشدار میدهد.
- •
- varargs: درباره متدهای vararg بالقوه ناامن هشدار میدهد.
- •
- none: تمام هشدارها را غیرفعال میکند.
به استثنای all و none، کلیدها میتوانند همراه با یادداشت @SuppressWarnings برای فرونشاندن هشدارها در بخشی از کد مبدأ که کامپایل میشود استفاده شوند.
بخش Examples of Using -Xlint keys را ببینید.
- -Xmaxerrs number
- حداکثر تعداد خطاهای قابل چاپ را تنظیم میکند.
- -Xmaxwarns number
- حداکثر تعداد هشدارهای قابل چاپ را تنظیم میکند.
- -Xpkginfo:[always, legacy, nonempty]
- با استفاده از یکی از گزینههای زیر مشخص میکند که دستور javac چه زمانی و چگونه فایلهای package-info.class را از فایلهای package-info.java تولید کند:
- always
- برای هر فایل package-info.java یک فایل package-info.class تولید میکند. این گزینه اگر از سامانههای ساختی مانند Ant استفاده میکنید که بررسی میکنند آیا هر فایل .java یک فایل متناظر .class دارد یا خیر، ممکن است مفید باشد.
- legacy
- تنها در صورتی یک فایل package-info.class تولید میکند که package-info.java حاوی یادداشت باشد. این گزینه اگر package-info.java فقط شامل توضیحات (comments) باشد، فایل package-info.class تولید نمیکند.
نکته: اگر تمام یادداشتهای موجود در فایل package-info.java دارای RetentionPolicy.SOURCE باشند، ممکن است یک فایل package-info.class تولید شود اما خالی باشد.
- nonempty
- تنها در صورتی یک فایل package-info.class تولید میکند که package-info.java حاوی یادداشتهایی با RetentionPolicy.CLASS یا RetentionPolicy.RUNTIME باشد.
- -Xplugin:name args
- نام و آرگومانهای اختیاری را برای اجرای یک افزونه مشخص میکند. در صورت ارائه args، باید name و args درون گیومه قرار گیرند یا نویسههای فاصله بین نام و همه آرگومانها به روش دیگری گریز داده (escape) شوند. برای جزئیات بیشتر درباره API افزونه، به مستندات API برای jdk.compiler/com.sun.source.util.Plugin مراجعه کنید.
- -Xprefer:[source, newer]
- با استفاده از یکی از گزینههای زیر مشخص میکند هنگام پیدا شدن همزمان یک فایل مبدأ و فایل کلاس برای کلاسی که بهطور ضمنی کامپایل شده است، کدام فایل خوانده شود. بخش Searching for Module, Package and Type Declarations را ببینید.
- •
- -Xprefer:newer: فایل تازهتر را از میان فایلهای مبدأ یا کلاس برای یک نوع میخواند (پیشفرض).
- •
- -Xprefer:source : فایل مبدأ را میخواند. هنگامی که میخواهید مطمئن شوید پردازندههای یادداشت میتوانند به یادداشتهای اعلانشده با سیاست نگهداری SOURCE دسترسی داشته باشند، از -Xprefer:source استفاده کنید. -Xprint نمایشی متنی از نوعهای مشخصشده را برای اهداف اشکالزدایی چاپ میکند. این گزینه پردازش حاشیهنویسی یا کامپایل را انجام نمیدهد. قالب خروجی ممکن است تغییر کند.
- -XprintProcessorInfo
- اطلاعاتی درباره اینکه پردازشگر برای پردازش چه حاشیهنویسیهایی فراخوانی شده است را چاپ میکند.
- -XprintRounds
- اطلاعات مربوط به دورهای اولیه و بعدی پردازش حاشیهنویسی را چاپ میکند.
- -Xstdout filename
- پیامهای کامپایلر را به فایل مشخصشده ارسال میکند. بهطور پیشفرض، پیامهای کامپایلر به System.err فرستاده میشوند.
متغیرهای محیطی (ENVIRONMENT VARIABLES)
CLASSPATH
اگر گزینهٔ --class-path یا هر یک از اشکال جایگزین آن مشخص نشده باشد، مسیر کلاس بهطور پیشفرض برابر با مقدار متغیر محیطی CLASSPATH (در صورت تنظیم بودن) خواهد بود. با این حال، توصیه میشود که این متغیر محیطی تنظیم نشود و در صورت نیاز، از گزینهٔ --class-path برای تعیین یک مقدار صریح برای مسیر کلاس استفاده گردد.
JDK_JAVAC_OPTIONS
محتوای متغیر محیطی JDK_JAVAC_OPTIONS که با فاصلهها ( ) یا نویسههای فاصله (\n، \t، \r، یا \f) جدا شده است، به عنوان فهرستی از آرگومانها به ابتدای آرگومانهای خط فرمان ارسالی به javac اضافه میشود.
نیازمندیهای کدگذاری برای متغیر محیطی، همانند خط فرمان javac در سیستم است. با محتوای متغیر محیطی JDK_JAVAC_OPTIONS دقیقاً مانند مواردی که در خط فرمان مشخص شده باشند رفتار میشود.
میتوان از نقلقول تکی (') یا نقلقول دوتایی (") برای محصور کردن آرگومانهایی که حاوی نویسههای فاصله هستند استفاده کرد. تمام محتوای بین نقلقول باز و اولین نقلقول بستهٔ منطبق، تنها با حذف جفت نقلقول حفظ میشود. در صورتی که نقلقول منطبق پیدا نشود، اجراکننده (launcher) با یک پیام خطا متوقف خواهد شد. فایلهای @files همانند مشخصشدن در خط فرمان پشتیبانی میشوند. با این حال، همانند @files، استفاده از نویسههای عمومی (wildcard) پشتیبانی نمیشود.
مثالهایی از نقلقول آرگومانهای حاوی نویسههای فاصله:
export JDK_JAVAC_OPTIONS='@"C:\white spaces\argfile"'
export JDK_JAVAC_OPTIONS='"@C:\white spaces\argfile"'
export JDK_JAVAC_OPTIONS='@C:\"white spaces"\argfile'
فایلهای آرگومان خط فرمان (COMMAND-LINE ARGUMENT FILES)
یک فایل آرگومان میتواند شامل گزینههای خط فرمان و نام فایلهای منبع در هر ترکیبی باشد. آرگومانهای درون یک فایل میتوانند با فاصله یا نویسههای خط جدید از هم جدا شوند. اگر نام یک فایل حاوی فاصلههای درونی باشد، کل نام فایل را درون علامت نقلقول دوتایی قرار دهید.
نامهای فایل درون یک فایل آرگومان، نسبت به دایرکتوری جاری سنجیده میشوند، نه محل قرارگیری فایل آرگومان. استفاده از نویسههای عمومی (*) در این فهرستها مجاز نیست (مانند تعیین *.java). استفاده از علامت اَتساین (@) برای تفسیر بازگشتی فایلها پشتیبانی نمیشود. گزینههای -J پشتیبانی نمیشوند زیرا به اجراکننده ارسال میشوند که از فایلهای آرگومان پشتیبانی نمیکند.
هنگام اجرای دستور javac، مسیر و نام هر فایل آرگومان را با نویسهٔ پیشوند اَتساین (@) وارد کنید. هنگامی که دستور javac با آرگومانی مواجه شود که با علامت اَتساین (@) آغاز میشود، محتویات آن فایل را در فهرست آرگومانها میگستراند..SS مثالهایی از استفاده از javac @filename
- فایل آرگومان منفرد
- میتوانید از یک فایل آرگومان منفرد به نام argfile برای نگهداری تمام آرگومانهای javac استفاده کنید:
javac @argfile
این فایل آرگومان میتواند شامل محتوای هر دو فایل نشاندادهشده در مثال دو فایل آرگومان در ادامه باشد.
- دو فایل آرگومان
- میتوانید دو فایل آرگومان ایجاد کنید: یکی برای گزینههای javac و دیگری برای نامهای فایلهای منبع. توجه داشته باشید که فهرستهای زیر هیچ نویسهٔ ادامهدهندهٔ خطی ندارند.
فایلی به نام options ایجاد کنید که حاوی موارد زیر باشد:
Linux و macOS:
-
-d classes -g -sourcepath /java/pubs/ws/1.3/src/share/classes
Windows:
-
-d classes -g -sourcepath C:\java\pubs\ws\1.3\src\share\classes
فایلی به نام sources ایجاد کنید که حاوی موارد زیر باشد:
-
MyClass1.java MyClass2.java MyClass3.java
سپس، دستور javac را به شکل زیر اجرا کنید:
javac @options @sources
- فایلهای آرگومان دارای مسیر
- فایلهای آرگومان میتوانند مسیر داشته باشند، اما هر نام فایلی درون این فایلها نسبت به دایرکتوری کاری فعلی سنجیده میشود (نه نسبت به path1 یا path2):
javac @path1/options @path2/sources
چینش کد منبع (ARRANGEMENT OF SOURCE CODE)
در زبان Java، کلاسها و رابطها (interfaces) میتوانند در بستهها، و بستهها در ماژولها سازماندهی شوند. javac انتظار دارد که چینش فیزیکی فایلهای منبع در دایرکتوریهای سیستم فایل، بازتابدهندهٔ سازماندهی کلاسها در بستهها، و بستهها در ماژولها باشد.
این یک قرارداد پذیرفتهشدهٔ گسترده است که نام ماژولها و نام بستهها با یک حرف کوچک، و نام کلاسها با یک حرف بزرگ آغاز شوند..SS چیدمان کد منبع برای یک بسته
هنگامی که کلاسها و رابطها در یک بسته سازماندهی میشوند، آن بسته بهصورت یک دایرکتوری و هر زیربسته بهصورت یک زیردایرکتوری نشان داده میشود.
برای نمونه:
- •
- بسته p بهصورت دایرکتوریای به نام p نمایش داده میشود.
- •
- بسته p.q -- یعنی، زیربسته q از بسته p -- بهصورت زیردایرکتوری q از دایرکتوری p نمایش داده میشود. بنابراین درخت دایرکتوری نمایشدهنده بسته p.q در ویندوز p\q و در سایر سیستمها p/q است.
- •
- بسته p.q.r بهصورت درخت دایرکتوری p\q\r (در ویندوز) یا p/q/r (در سایر سیستمها) نمایش داده میشود.
درون یک دایرکتوری یا زیردایرکتوری، فایلهای .java نشاندهنده کلاسها و رابطهای موجود در بسته یا زیربسته متناظر هستند.
برای نمونه:
- •
- کلاس X اعلانشده در بسته p با فایل X.java در دایرکتوری p نمایش داده میشود.
- •
- کلاس Y اعلانشده در بسته p.q با فایل Y.java در زیردایرکتوری q از دایرکتوری p نمایش داده میشود.
- •
- کلاس Z اعلانشده در بسته p.q.r با فایل Z.java در زیردایرکتوری r از p\q (در ویندوز) یا p/q (در سایر سیستمها) نمایش داده میشود.
در برخی شرایط، مناسب است که کد به دایرکتوریهای جداگانه تقسیم شود، بهطوری که ساختار هر یک طبق توضیحات بالا باشد، و فهرست تجمیعی دایرکتوریها به javac مشخص گردد.
چیدمان کد منبع برای یک ماژول
در زبان Java، یک ماژول مجموعهای از بستهها است که برای استفاده مجدد طراحی شدهاند. علاوه بر فایلهای .java برای کلاسها و رابطها، هر ماژول دارای یک فایل منبع به نام module-info.java است که:
- 1.
- نام ماژول را اعلان میکند؛
- 2.
- بستههای صادرشده توسط ماژول را فهرست میکند (تا امکان استفاده مجدد توسط سایر ماژولها فراهم شود)؛
- 3.
- سایر ماژولهای مورد نیاز ماژول را فهرست میکند (برای استفاده مجدد از بستههای صادرشده آنها).
هنگامی که بستهها در یک ماژول سازماندهی میشوند، ماژول توسط یک یا چند دایرکتوری نمایش داده میشود که نشاندهنده بستههای درون ماژول هستند و یکی از آنها حاوی فایل module-info.java است. استفاده از یک دایرکتوری واحد، همنام با ماژول، برای نگهداری فایل module-info.java در کنار درخت دایرکتوری نشاندهنده بستههای ماژول (یعنی همان سلسلهمراتب بستهها که در بالا توضیح داده شد) ممکن است راحتتر باشد، اما الزامی نیست. چیدمان دقیق کد منبع برای یک ماژول معمولاً بر اساس شیوهنامههای اتخاذشده توسط یک محیط توسعه (IDE) یا سامانه ساخت تعیین میشود.
برای نمونه:
- •
- ماژول a.b.c ممکن است در تمام سیستمها توسط دایرکتوری a.b.c نمایش داده شود.
- •
- اعلان ماژول توسط فایل module-info.java در دایرکتوری a.b.c نمایش داده میشود.
- •
- اگر ماژول حاوی بسته p.q.r باشد، آنگاه دایرکتوری a.b.c شامل درخت دایرکتوری p\q\r (در ویندوز) یا p/q/r (در سایر سیستمها) خواهد بود.
محیط توسعه ممکن است سلسلهمراتبی از دایرکتوریها را بین دایرکتوری همنام با ماژول و فایلهای منبعی که قرار است توسط javac خوانده شوند، تعیین کند.
برای نمونه:
- •
- ماژول a.b.c ممکن است با دایرکتوری a.b.c نمایش داده شود.
- •
- اعلان ماژول و بستههای ماژول ممکن است در زیردایرکتوری خاصی از a.b.c قرار گیرند، مانند src\main\java (در ویندوز) یا src/main/java (در سایر سیستمها)..SH "پیکربندی کامپایل (CONFIGURING A COMPILATION)"
این بخش نحوهٔ پیکربندی javac را برای انجام یک کامپایل پایهای شرح میدهد.
برای جزئیات بیشتر جهت استفاده در هنگام کامپایل برای نسخهای از پلتفرم که از ماژولها پشتیبانی میکند، بخش Configuring the Module System را ببینید.
فایلهای منبع (Source Files)
- •
- فایلهای منبعی را که قرار است کامپایل شوند در خط فرمان مشخص کنید.
اگر هیچ خطای کامپایلی وجود نداشته باشد، فایلهای کلاس متناظر در دایرکتوری خروجی قرار خواهند گرفت.
برخی سیستمها ممکن است طول خط فرمان را محدود کنند؛ برای دور زدن این محدودیتها، میتوانید از فایلهای آرگومان استفاده کنید.
هنگام کامپایل کد برای ماژولها، میتوانید فایلهای منبع را به صورت غیرمستقیم و با استفاده از گزینهٔ --module یا -m نیز مشخص کنید.
دایرکتوری خروجی (Output Directory)
- •
- از گزینهٔ -d برای تعیین یک دایرکتوری خروجی جهت قرار دادن فایلهای کلاس کامپایلشده استفاده کنید.
این ساختار معمولاً در یک سلسلهمراتب بستهای سازماندهی میشود، مگر اینکه در حال کامپایل کد منبع از چندین ماژول باشید که در این صورت به عنوان یک سلسلهمراتب ماژولی سازماندهی خواهد شد.
پس از اتمام کامپایل، اگر در حال کامپایل یک یا چند ماژول هستید، میتوانید دایرکتوری خروجی را در مسیر ماژول (module path) برای راهانداز جاوا قرار دهید؛ در غیر این صورت، میتوانید دایرکتوری خروجی را در مسیر کلاس (class path) برای راهانداز جاوا قرار دهید.
کد از پیشکامپایلشده (Precompiled Code)
کدی که قرار است کامپایل شود ممکن است به کتابخانههایی فراتر از آنچه توسط پلتفرم ارائه شده ارجاع دهد. در این صورت، باید این کتابخانهها را در مسیر کلاس یا مسیر ماژول قرار دهید. اگر کد کتابخانه در یک ماژول نیست، آن را در مسیر کلاس قرار دهید؛ اگر در یک ماژول است، آن را در مسیر ماژول بگذارید.
- •
- از گزینهٔ --class-path برای تعیین کتابخانههایی که باید در مسیر کلاس قرار گیرند استفاده کنید. مکانها در مسیر کلاس باید در یک سلسلهمراتب بستهای سازماندهی شوند. همچنین میتوانید از اشکال دیگر این گزینه استفاده کنید: -classpath یا -cp.
- •
- از گزینهٔ --module-path برای تعیین کتابخانههایی که باید در مسیر ماژول قرار گیرند استفاده کنید. مکانها در مسیر ماژول باید خود ماژول یا دایرکتوریهایی از ماژولها باشند. همچنین میتوانید از شکل دیگر این گزینه استفاده کنید: -p.
برای جزئیات بیشتر در مورد نحوهٔ تغییر پیکربندی پیشفرض ماژولهای کتابخانه، بخش Configuring the Module System را ببینید.
نکته: گزینههای مربوط به مسیر کلاس و مسیر ماژول مانعةالجمع نیستند، اگرچه مشخص کردن مسیر کلاس هنگام کامپایل کد برای یک یا چند ماژول معمول نیست.
فایلهای منبع اضافی (Additional Source Files)
کدی که قرار است کامپایل شود ممکن است به انواعی در فایلهای منبع اضافی که در خط فرمان مشخص نشدهاند ارجاع دهد. در این صورت، باید آن فایلهای منبع را در مسیر منبع (source path) یا مسیر ماژول قرار دهید. شما تنها میتوانید یکی از این گزینهها را مشخص کنید: اگر کدی را برای یک ماژول کامپایل نمیکنید، یا تنها کدی را برای یک ماژول واحد کامپایل میکنید، از مسیر منبع استفاده کنید؛ اگر کدی را برای چندین ماژول کامپایل میکنید، از مسیر منبع ماژول (module source path) استفاده نمایید.
- •
- از گزینهٔ --source-path برای تعیین مکانهای فایلهای منبع اضافی که ممکن است توسط javac خوانده شوند استفاده کنید. مکانها در مسیر منبع باید در یک سلسلهمراتب بستهای سازماندهی شوند. همچنین میتوانید از شکل دیگر این گزینه استفاده کنید: -sourcepath.
- •
- از گزینهٔ --module-source-path یک یا چند بار برای تعیین مکان فایلهای منبع اضافی در ماژولهای مختلف که ممکن است توسط javac خوانده شوند، یا هنگام کامپایل فایلهای منبع در چندین ماژول استفاده کنید. میتوانید مکانها را برای هر ماژول به صورت جداگانه مشخص کنید، یا فایلهای منبع را طوری سازماندهی کنید که بتوانید مکانها را به صورت یکجا مشخص نمایید. برای جزئیات بیشتر، بخش The Module Source Path Option را ببینید.
اگر میخواهید بتوانید به انواعی در فایلهای منبع اضافی ارجاع دهید اما مایل نیستید که آنها کامپایل شوند، از گزینهٔ -implicit استفاده کنید.
نکته: اگر کدی را برای چندین ماژول کامپایل میکنید، باید همیشه یک مسیر منبع ماژول را مشخص کنید، و تمام فایلهای منبع مشخصشده در خط فرمان باید در یکی از دایرکتوریهای موجود در مسیر منبع ماژول، یا در زیردایرکتوریهای آن قرار داشته باشند..SS مثال کامپایل چندین فایل منبع
این مثال، فایلهای منبع Aloha.java، GutenTag.java، Hello.java و Hi.java را در بستهٔ greetings کامپایل میکند.
لینوکس و macOS:
-
% javac greetings/*.java % ls greetings Aloha.class GutenTag.class Hello.class Hi.class Aloha.java GutenTag.java Hello.java Hi.java
ویندوز:
-
C:\>javac greetings\*.java C:\>dir greetings Aloha.class GutenTag.class Hello.class Hi.class Aloha.java GutenTag.java Hello.java Hi.java
مثال مشخص کردن مسیر کلاس کاربر (User Class Path)
پس از تغییر یکی از فایلهای منبع در مثال قبلی، آن را مجدداً کامپایل کنید:
لینوکس و macOS:
-
pwd /examples javac greetings/Hi.java
ویندوز:
-
C:\>cd \examples C:\>javac greetings\Hi.java
از آنجا که greetings.Hi به کلاسهای دیگر در بستهٔ greetings ارجاع میدهد، کامپایلر باید بتواند این کلاسهای دیگر را پیدا کند. مثال قبلی به این دلیل کار میکند که مسیر پیشفرض کلاس کاربر، دایرکتوریای است که دایرکتوری بسته را در بر دارد. اگر میخواهید این فایل را بدون نگرانی از اینکه در کدام دایرکتوری هستید مجدداً کامپایل کنید، دایرکتوری examples را با تنظیم CLASSPATH به مسیر کلاس کاربر اضافه کنید. این مثال از گزینهٔ -classpath استفاده میکند.
لینوکس و macOS:
javac -classpath /examples /examples/greetings/Hi.java
ویندوز:
C:\>javac -classpath \examples \examples\greetings\Hi.java
اگر greetings.Hi را طوری تغییر دهید که از یک ابزار banner استفاده کند، آن ابزار نیز باید از طریق مسیر کلاس کاربر در دسترس باشد.
لینوکس و macOS:
-
javac -classpath /examples:/lib/Banners.jar \ /examples/greetings/Hi.java
ویندوز:
-
C:\>javac -classpath \examples;\lib\Banners.jar ^ \examples\greetings\Hi.java
برای اجرای یک کلاس در بستهٔ greetings، برنامه نیاز به دسترسی به بستهٔ greetings و همچنین کلاسهایی دارد که کلاسهای greetings از آنها استفاده میکنند.
لینوکس و macOS:
java -classpath /examples:/lib/Banners.jar greetings.Hi
ویندوز:
C:\>java -classpath \examples;\lib\Banners.jar greetings.Hi
اگر میخواهید ماژولهای بیشتری را در کامپایل خود بگنجانید، از گزینهٔ --add-modules استفاده کنید. این کار ممکن است زمانی لازم باشد که در حال کامپایل کدی هستید که درون یک ماژول قرار ندارد، یا در یک ماژول خودکار (automatic module) قرار دارد، و کد به API موجود در ماژولهای دیگر ارجاع میدهد.
اگر میخواهید مجموعه ماژولها را در کامپایل خود محدود کنید، از گزینهٔ --limit-modules استفاده کنید. این کار زمانی میتواند مفید باشد که میخواهید اطمینان حاصل کنید کدی که کامپایل میکنید، قابلیت اجرا روی سیستمی با مجموعهٔ محدودی از ماژولهای نصبشده را دارد.
اگر میخواهید کپسولهسازی را بشکنید و مشخص کنید که بستههای اضافی باید به عنوان بستههای صادرشده (exported) از یک ماژول در نظر گرفته شوند، از گزینهٔ --add-exports استفاده کنید. این کار ممکن است هنگام انجام آزمون جعبهسفید (white-box testing) مفید باشد؛ اتکا به دسترسی به API داخلی در کد محصول نهایی (production) به شدت نهی میشود.
اگر میخواهید مشخص کنید که بستههای بیشتری باید به عنوان نیازمندیهای یک ماژول در نظر گرفته شوند، از گزینهٔ --add-reads استفاده کنید. این کار ممکن است هنگام انجام آزمون جعبهسفید مفید باشد؛ اتکا به دسترسی به API داخلی در کد محصول نهایی به شدت نهی میشود.
میتوانید با استفاده از گزینهٔ --patch-module محتوای اضافی را به هر ماژولی وصله (patch) کنید. برای جزئیات بیشتر به بخش [Patching a Module] مراجعه کنید.
جستجو برای اعلانهای ماژول، بسته و نوع (SEARCHING FOR MODULE, PACKAGE AND TYPE DECLARATIONS)
برای کامپایل یک فایل منبع، کامپایلر اغلب به اطلاعاتی درباره یک ماژول یا نوع (type) نیاز دارد، در حالی که اعلان (declaration) آن در فایلهای منبع مشخصشده در خط فرمان وجود ندارد.
دستور javac به اطلاعات نوع برای هر کلاس یا رابطی (interface) که در فایل منبع استفاده شده، گسترش یافته (extended) یا پیادهسازی شده (implemented) نیاز دارد. این شامل کلاسها و رابطهایی که به صراحت در فایل منبع ذکر نشدهاند، اما اطلاعات را از طریق توارث فراهم میکنند نیز میشود.
برای نمونه، هنگامی که یک زیرکلاس (subclass) از java.awt.Window میسازید، شما همچنین از کلاسهای اجدادی Window استفاده میکنید: java.awt.Container، java.awt.Component و java.lang.Object.
هنگام کامپایل کد برای یک ماژول، کامپایلر همچنین نیاز دارد که اعلان آن ماژول در دسترس باشد.
یک جستجوی موفق ممکن است یک فایل کلاس، یک فایل منبع یا هر دو را تولید کند. اگر هر دو یافت شوند، میتوانید از گزینهٔ -Xprefer استفاده کنید تا به کامپایلر دستور دهید از کدام یک استفاده کند.
اگر یک جستجو فایل منبعی را بیابد و استفاده کند، آنگاه به طور پیشفرض javac آن فایل منبع را کامپایل میکند. این رفتار را میتوان با -implicit تغییر داد.
کامپایلر ممکن است تا پس از تکمیل پردازش حاشیهنویسی (annotation processing)، متوجه نیاز به برخی اطلاعات نوع نشود. هنگامی که اطلاعات نوع در یک فایل منبع یافت میشود و هیچ گزینهٔ -implicit مشخص نشده باشد، کامپایلر هشداری صادر میکند مبنی بر اینکه فایل بدون قرار گرفتن تحت پردازش حاشیهنویسی در حال کامپایل شدن است. برای غیرفعال کردن هشدار، یا فایل را در خط فرمان مشخص کنید (تا مشمول پردازش حاشیهنویسی شود) یا از گزینهٔ -implicit برای تعیین اینکه آیا فایلهای کلاس برای چنین فایلهای منبعی تولید شوند یا خیر، استفاده کنید.
روشی که javac اعلانهای آن نوعها را مکانیابی میکند بستگی به این دارد که آیا ارجاع درون کدِ یک ماژول قرار دارد یا خیر.
جستجوی مسیرهای بستهمحور (Searching Package Oriented Paths)
هنگام جستجوی یک فایل منبع یا کلاس در مسیری متشکل از مکانهای بستهمحور، javac هر مکان در مسیر را به نوبت برای احتمال وجود فایل بررسی میکند. نخستین رخداد یک فایل خاص، هرگونه رخداد بعدی فایلهای همنام را سایهاندازی (پنهان) میکند. این سایهاندازی بر جستجو برای فایلهایی با نام متفاوت تأثیری ندارد. این ویژگی میتواند هنگام جستجوی فایلهای منبع که ممکن است در مکانهای متفاوتی گروهبندی شده باشند، مانند کد مشترک، کد وابسته به پلتفرم و کد تولیدشده، بسیار مناسب باشد. همچنین میتواند هنگام تزریق نسخههای جایگزین یک فایل کلاس به درون یک بسته، به منظور اشکالزدایی یا سایر دلایل ابزار دقیق، مفید باشد. اما این کار میتواند خطرناک نیز باشد؛ مانند زمانی که نسخههای متفاوت و ناسازگار یک کتابخانه در مسیر کلاس (class path) قرار داده شوند..SS جستجوی مسیرهای مبتنی بر ماژول
پیش از پویش هر یک از مسیرهای ماژول برای اعلانهای بسته یا نوع، javac مسیرها و مکانهای زیر را بهطور تنبل (lazy) بررسی میکند تا ماژولهایی را که در کامپایل استفاده خواهند شد مشخص کند:
- •
- مسیر مبدأ ماژول (گزینهٔ --module-source-path را ببینید)
- •
- مسیر ماژولهای قابل ارتقا (گزینهٔ --upgrade-module-path را ببینید)
- •
- ماژولهای سیستم (گزینهٔ --system را ببینید)
- •
- مسیر ماژول کاربر (گزینهٔ --module-path را ببینید)
برای هر ماژول، نخستین رخداد ماژول در طول پویش، هرگونه پیدایش بعدیِ ماژولی با نام مشابه را کاملاً میپوشاند (پنهان میکند). در حین مکانیابی ماژولها، javac قادر است بستههای صادرشده توسط ماژول را مشخص کند و به هر ماژول یک مسیر بستهمحور متناظر با محتویات آن ماژول اختصاص دهد. برای هر ماژولی که پیشتر کامپایل شده است، این مسیر معمولاً یک مدخل واحد برای یک دایرکتوری یا فایلی خواهد بود که سلسلهمراتبی درونی شبیه به دایرکتوری ارائه میدهد، مانند یک فایل JAR. بدین ترتیب، هنگام جستجو برای نوعی که در بستهای قرار دارد که مشخص شده توسط یک ماژول صادر گردیده، javac میتواند اعلان آن را بهطور مستقیم و کارآمد پیدا کند.
جستجو برای اعلان یک ماژول
اگر ماژول قبلاً کامپایل شده باشد، اعلان ماژول در فایلی با نام module-info.class در ریشهٔ سلسلهمراتب بستهها برای محتوای ماژول قرار دارد.
اگر ماژول یکی از مواردی باشد که هماکنون در حال کامپایل هستند، اعلان ماژول یا فایلی با نام module-info.class در ریشهٔ سلسلهمراتب بستهها برای آن ماژول در دایرکتوری خروجی کلاسها خواهد بود، یا فایلی با نام module-info.java در یکی از مکانهای روی مسیر مبدأ یا روی مسیر مبدأ ماژول برای آن ماژول.
جستجو برای اعلان یک نوع در صورتی که ارجاع درون یک ماژول نباشد
هنگام جستجو برای نوعی که در کدی خارج از یک ماژول به آن ارجاع داده شده است، javac مکانهای زیر را بررسی خواهد کرد:
- •
- کلاسهای پلتفرم (یا انواع موجود در بستههای صادرشدهٔ ماژولهای پلتفرم) (این مورد تنها برای فایلهای کلاس کامپایلشده است.)
- •
- انواع موجود در بستههای صادرشدهٔ هر یک از ماژولهای موجود در مسیر ماژول، در صورت وجود. (این مورد تنها برای فایلهای کلاس کامپایلشده است.)
- •
- انواع موجود در بستههای روی مسیر کلاس (class path) و/یا مسیر مبدأ (source path):
- •
- اگر هر دو مشخص شده باشند، javac در مسیر کلاس به دنبال فایلهای کلاس کامپایلشده و در مسیر مبدأ به دنبال فایلهای مبدأ میگردد.
- •
- اگر مسیر کلاس مشخص شده باشد اما مسیر مبدأ مشخص نشده باشد، javac هم به دنبال فایلهای کلاس کامپایلشده و هم به دنبال فایلهای مبدأ در مسیر کلاس میگردد.
- •
- اگر مسیر کلاس مشخص نشده باشد، مقدار پیشفرض آن دایرکتوری جاری خواهد بود.
هنگام جستجوی یک نوع در مسیر کلاس و/یا مسیر مبدأ، چنانچه هم فایل کلاس کامپایلشده و هم فایل مبدأ پیدا شوند، بهطور پیشفرض فایلی که اخیراً تغییر یافته استفاده خواهد شد. اگر فایل مبدأ جدیدتر باشد، کامپایل خواهد شد و ممکن است جایگزین هر نسخهٔ از پیش کامپایلشدهٔ آن فایل شود. میتوانید از گزینهٔ -Xprefer برای تغییر این رفتار پیشفرض استفاده کنید.
جستجو برای اعلان یک نوع در صورتی که ارجاع درون یک ماژول باشد
هنگام جستجو برای نوعی که در کدی درون یک ماژول به آن ارجاع داده شده است، javac اعلان ماژول دربرگیرنده را بررسی میکند تا مشخص شود آیا آن نوع در بستهای قرار دارد که از ماژول دیگری صادر شده و توسط ماژول دربرگیرنده قابل خواندن است یا خیر. اگر چنین باشد، javac ساده و مستقیم به تعریف آن ماژول میرود تا تعریف نوع مورد نیاز را بیابد. مگر در حالتی که ماژول، یکی دیگر از ماژولهای در حال کامپایل باشد، javac تنها به دنبال فایلهای کلاس کامپایلشده خواهد گشت. به عبارت دیگر، javac در ماژولهای پلتفرم یا ماژولهای موجود در مسیر ماژول، به دنبال فایلهای مبدأ نخواهد گشت.
چنانچه نوع مورد ارجاع در ماژول خواندنی دیگری نباشد، javac ماژول در حال کامپایل را بررسی میکند تا برای یافتن اعلان آن نوع تلاش کند. javac اعلان آن نوع را به شرح زیر جستجو خواهد کرد:
- •
- فایلهای مبدأ مشخصشده در خط فرمان یا در مسیر مبدأ یا مسیر مبدأ ماژول.
- •
- فایلهای پیشتر کامپایلشده در دایرکتوری خروجی..SH "سلسلهمراتبهای دایرکتوری (DIRECTORY HIERARCHIES)"
javac عموماً فرض میکند که فایلهای مبدأ و فایلهای کلاس کامپایلشده در یک سلسلهمراتب دایرکتوریِ سیستم فایل، یا در نوعی از فایل که از سلسلهمراتب دایرکتوری داخلی پشتیبانی میکند (مانند یک فایل JAR)، سازماندهی خواهند شد. سه نوع مختلف از سلسلهمراتب پشتیبانی میشود: یک سلسلهمراتب بسته (package hierarchy)، یک سلسلهمراتب ماژول (module hierarchy)، و یک سلسلهمراتب مبدأ ماژول (module source hierarchy).
در حالی که javac درباره سازماندهی کد مبدأ انعطافپذیری نسبتاً بالایی دارد (فراتر از این انتظار که مبدأ در یک یا چند سلسلهمراتب بسته سازماندهی شود) و عموماً میتواند با ساختارهای تعیینشده توسط محیطهای توسعه و ابزارهای ساخت سازگار شود، ابزارهای Java بهطور کلی، و بهویژه javac و اجراکننده Java، در رابطه با سازماندهی فایلهای کلاس کامپایلشده سختگیرانهتر هستند و این فایلها بسته به شرایط، باید در سلسلهمراتبهای بسته یا سلسلهمراتبهای ماژول سازماندهی شوند.
مکان این سلسلهمراتبها از طریق گزینههای خط فرمان به javac مشخص میشود، گزینههایی که نام آنها معمولاً به "path" ختم میشود؛ مانند --source-path یا --class-path. همچنین بهعنوان یک قاعده کلی، گزینههای مسیری که نام آنها شامل کلمه module است، مانند --module-path، برای مشخص کردن سلسلهمراتبهای ماژول به کار میروند؛ اگرچه برخی گزینههای مسیر مربوط به ماژول اجازه میدهند که یک سلسلهمراتب بسته بر پایه هر ماژول مشخص شود. سایر گزینههای مسیر برای تعیین سلسلهمراتبهای بسته به کار میروند.
سلسلهمراتب بسته (Package Hierarchy)
در یک سلسلهمراتب بسته، دایرکتوریها و زیردایرکتوریها برای نشان دادن بخشهای تشکیلدهندهٔ نام بسته استفاده میشوند، بهطوری که فایل مبدأ یا فایل کلاس کامپایلشده برای یک نوع (type) بهعنوان فایلی با پسوند .java یا .class در درونیترین دایرکتوری ذخیره میشود.
برای نمونه، در یک سلسلهمراتب بسته، فایل مبدأ برای کلاسی به نام com.example.MyClass در فایل com/example/MyClass.java ذخیره خواهد شد.
سلسلهمراتب ماژول (Module Hierarchy)
در یک سلسلهمراتب ماژول، دایرکتوریهای سطح اول بر اساس ماژولهای موجود در سلسلهمراتب نامگذاری میشوند؛ در داخل هر یک از آن دایرکتوریها، محتویات ماژول در سلسلهمراتبهای بسته سازماندهی میشوند.
برای نمونه، در یک سلسلهمراتب ماژول، فایل کلاس کامپایلشده برای نوعی به نام com.example.MyClass در ماژولی به نام my.library، در مسیر my.library/com/example/MyClass.class ذخیره خواهد شد.
دایرکتوریهای خروجی گوناگون استفادهشده توسط javac (دایرکتوری خروجی کلاس، دایرکتوری خروجی مبدأ، و دایرکتوری خروجی سرآیند بومی) هنگامی که چندین ماژول در حال کامپایل باشند، همگی در یک سلسلهمراتب ماژول سازماندهی خواهند شد.
سلسلهمراتب مبدأ ماژول (Module Source Hierarchy)
اگرچه مبدأ هر ماژول مجزا همیشه باید در یک سلسلهمراتب بسته سازماندهی شود، ممکن است گروهبندی این سلسلهمراتبها در یک سلسلهمراتب مبدأ ماژول راحتتر باشد. این ساختار شبیه به یک سلسلهمراتب ماژول است، با این تفاوت که ممکن است دایرکتوریهای واسطی بین دایرکتوری ماژول و دایرکتوری ریشهٔ سلسلهمراتب بسته برای کد مبدأ آن ماژول وجود داشته باشد.
برای نمونه، در یک سلسلهمراتب مبدأ ماژول، فایل مبدأ برای نوعی به نام com.example.MyClass در ماژولی به نام my.library ممکن است در فایلی مانند my.library/src/main/java/com/example/MyClass.java ذخیره شود.
گزینه مسیر مبدأ ماژول (THE MODULE SOURCE PATH OPTION)
گزینه --module-source-path دارای دو فرم است: یک فرم مخصوص هر ماژول، که در آن یک مسیر بسته برای هر ماژول حاوی کد جهت کامپایل مشخص میشود؛ و یک فرم الگوی ماژول، که در آن مسیر مبدأ برای هر ماژول توسط یک الگو تعیین میشود. فرم مخصوص هر ماژول عموماً زمانی که تنها تعداد کمی ماژول دخیل هستند برای استفاده سادهتر است؛ فرم الگوی ماژول زمانی میتواند مناسبتر باشد که تعداد ماژولها زیاد بوده و ماژولها به شیوهای منظم سازماندهی شده باشند که بتوان آن را با یک الگو توصیف کرد.
میتوان چندین نمونه از گزینه --module-source-path را مشخص کرد، که هر کدام یا از فرم الگوی ماژول یا از فرم مخصوص هر ماژول استفاده میکنند، با رعایت محدودیتهای زیر:
- •
- فرم الگوی ماژول حداکثر یک بار میتواند استفاده شود
- •
- فرم مخصوص هر ماژول برای هر ماژول معین حداکثر یک بار میتواند استفاده شود
اگر از فرم مخصوص هر ماژول برای هر ماژولی استفاده شود، مسیر جستجوی مربوطه جایگزین هر مسیری میشود که ممکن بود در غیر این صورت از فرم الگوی ماژول استنباط شود..SS "شکل مختص ماژول (Module-specific form)"
شکل مختص ماژول اجازه میدهد تا یک مسیر جستجوی صریح برای هر ماژول مشخص تعیین شود. این شکل به صورت زیر است:
- •
- --module-source-path module-name=file-path (path-separator file-path)*
نویسهٔ جداکنندهٔ مسیر در Windows برابر با ; و در غیر این صورت : است.
نکته: این شکل مشابه با شکل مورد استفاده برای گزینهٔ --patch-module است.
شکل الگوی ماژول (Module-pattern form)
شکل الگوی ماژول امکان تعیین مختصر مسیر منبع ماژول را برای هر تعداد ماژول که به شکلی منظم سازماندهی شدهاند، فراهم میکند.
- •
- --module-source-path pattern
الگو با قواعد زیر تعریف میشود که به ترتیب اعمال میگردند:
- •
- آرگومان به عنوان مجموعهای از بخشها در نظر گرفته میشود که توسط نویسهٔ جداکنندهٔ مسیر (; در Windows و در غیر این صورت :) از یکدیگر جدا شدهاند.
- •
- هر بخشی که شامل آکولادهایی به شکل زیر باشد
-
string1{alt1 ( ,alt2 )* } string2
جایگزینشده با مجموعهای از بخشها در نظر گرفته میشود که با "بسط دادن" آکولادها تشکیل شدهاند:
-
string1 alt1 string2 string1 alt2 string2 and so on...
آکولادها میتوانند تودرتو باشند.
این قاعده برای تمام چنین کاربردهایی از آکولاد اعمال میشود.
- •
- هر بخش باید حداکثر شامل یک ستاره (*) باشد. اگر بخشی فاقد ستاره باشد، به گونهای در نظر گرفته میشود که گویی نویسهٔ جداکنندهٔ فایل و یک ستاره به انتهای آن الحاق شده است.
برای هر ماژول M، مسیر منبع آن ماژول از مجموعهای از بخشها تشکیل میشود که با جایگزین کردن نام ماژول M به جای ستاره در هر بخش حاصل میآیند.
نکته: در این زمینه، ستاره صرفاً به عنوان یک نشانگر ویژه برای مشخص کردن موقعیت نام ماژول در مسیر استفاده شده است. نباید آن را با کاربرد * به عنوان نویسهٔ عام (wildcard) نام فایل، آنگونه که در بیشتر سیستمعاملها وجود دارد، اشتباه گرفت.
وصلهکردن ماژولها (PATCHING MODULES)
دستور javac اجازه میدهد هر محتوایی، چه در قالب کد منبع و چه به صورت کامپایلشده، با استفاده از گزینهٔ --patch-module به هر ماژولی وصله شود. ممکن است بخواهید این کار را برای کامپایل پیادهسازیهای جایگزین یک کلاس انجام دهید تا در زمان اجرا به یک JVM وصله شود، یا برای تزریق کلاسهای اضافی به ماژول، مانند هنگام آزمایش (تست).
شکل این گزینه عبارت است از:
- •
- --patch-module module-name=file-path (path-separator file-path )*
نویسهٔ جداکنندهٔ مسیر در Windows برابر با ; و در غیر این صورت : است. مسیرهای ارائهشده برای ماژول باید ریشهٔ یک سلسلهمراتب بستهای (package hierarchy) را برای محتویات ماژول مشخص کنند.
این گزینه حداکثر یکبار برای هر ماژول مشخص قابل ارائه است. هر محتوایی در مسیر، هر محتوای همنام دیگری را که در ادامه مسیر یا در ماژول وصلهشده قرار دارد، پنهان خواهد کرد.
هنگام وصلهکردن کد منبع به بیش از یک ماژول، گزینهٔ --module-source-path نیز باید استفاده شود تا دایرکتوری خروجی در یک سلسلهمراتب ماژولی سازماندهی شده و توانایی نگهداری فایلهای کلاس کامپایلشده را برای ماژولهای در حال کامپایل داشته باشد..SH "پردازش حاشیهنویسی (ANNOTATION PROCESSING)"
دستور javac پشتیبانی مستقیمی را برای پردازش حاشیهنویسی فراهم میکند.
رابط برنامهنویسی نرمافزار (API) برای پردازندههای حاشیهنویسی در بستهها و زیربستههای javax.annotation.processing و javax.lang.model تعریف شده است.
نحوه کارکرد پردازش حاشیهنویسی
مگر در حالتی که پردازش حاشیهنویسی با گزینه -proc:none غیرفعال شده باشد، کامپایلر به جستجوی تمامی پردازندههای حاشیهنویسی در دسترس میپردازد. مسیر جستجو را میتوان با گزینه -processorpath مشخص کرد. اگر مسیری مشخص نشده باشد، از مسیر کلاس کاربر (user class path) استفاده میشود. پردازندهها با استفاده از فایلهای پیکربندی ارائهدهنده سرویس با نام META-INF/services/javax.annotation.processing.Processor در مسیر جستجو شناسایی میشوند. این فایلها باید حاوی نام پردازندههای حاشیهنویسی مورد استفاده باشند که در هر خط یک مورد درج شده است. همچنین، پردازندهها را میتوان بهطور صریح با استفاده از گزینه -processor مشخص کرد.
پس از پیمایش فایلهای منبع و کلاسها در خط فرمان برای تعیین اینکه چه حاشیهنویسیهایی وجود دارند، کامپایلر از پردازندهها پرسوجو میکند تا مشخص شود چه حاشیهنویسیهایی را پردازش میکنند. هنگامی که تطابقی یافت شود، پردازنده فراخوانی میشود. یک پردازنده میتواند حاشیهنویسیهایی را که پردازش میکند تصاحب نماید؛ در این صورت هیچ تلاش دیگری برای یافتن پردازنده برای آن حاشیهنویسیها صورت نخواهد گرفت. پس از تصاحب تمامی حاشیهنویسیها، کامپایلر برای پردازندههای اضافی جستجو نخواهد کرد.
اگر پردازندهای فایلهای منبع جدیدی تولید کند، دور دیگری از پردازش حاشیهنویسی رخ میدهد: هر فایل منبع تازه تولیدشده پیمایش میشود و حاشیهنویسیهای آن همانند گذشته پردازش میگردند. هر پردازندهای که در دورهای پیشین فراخوانی شده باشد، در تمام دورهای پس از آن نیز فراخوانی میشود. این روند تا زمانی که هیچ فایل منبع جدیدی تولید نشود ادامه مییابد.
پس از رخ دادن دوری که در آن هیچ فایل منبع جدیدی تولید نشود، پردازندههای حاشیهنویسی برای آخرین بار فراخوانی میشوند تا فرصتی برای تکمیل کارهای باقیمانده به آنها داده شود. در نهایت، مگر در حالتی که گزینه -proc:only استفاده شده باشد، کامپایلر فایلهای منبع اولیه و تمامی فایلهای منبع تولیدشده را کامپایل میکند.
اگر از پردازنده حاشیهنویسی استفاده میکنید که فایلهای منبع دیگری را برای گنجانده شدن در فرایند کامپایل تولید میکند، میتوانید یک ماژول پیشفرض برای استفاده در فایلهای تازه تولیدشده مشخص کنید، تا هنگامی که اعلان ماژول تولید نشده باشد مورد استفاده قرار گیرد. در این حالت، از گزینه --default-module-for-created-files استفاده کنید.
محیط کامپایل و محیط زمان اجرا
اعلانها در فایلهای منبع و فایلهای کلاس از پیش کامپایلشده، توسط javac در یک محیط کامپایل بررسی میشوند که از محیط زمان اجرا مورد استفاده برای اجرای خود javac مجزا است. اگرچه شباهتی تعمدی میان بسیاری از گزینههای javac و گزینههای همنام در launcher جاوا وجود دارد (مانند --class-path، --module-path و غیره)، اما درک این نکته اهمیت دارد که بهطور کلی گزینههای javac صرفاً بر محیطی که فایلهای منبع در آن کامپایل میشوند اثر میگذارند و عملکرد خود javac را تحت تأثیر قرار نمیدهند.
تمایز میان محیط کامپایل و محیط زمان اجرا در هنگام استفاده از پردازندههای حاشیهنویسی بسیار چشمگیر است. اگرچه پردازندههای حاشیهنویسی عناصری (اعلانها) را پردازش میکنند که در محیط کامپایل قرار دارند، اما خود پردازنده حاشیهنویسی در محیط زمان اجرا به اجرا درمیآید. اگر یک پردازنده حاشیهنویسی به کتابخانههایی وابسته باشد که در قالب ماژول نیستند، میتوان آن کتابخانهها را در کنار خود پردازنده حاشیهنویسی در مسیر پردازنده قرار داد. (گزینه --processor-path را ببینید.) اگر پردازنده حاشیهنویسی و وابستگیهای آن در قالب ماژول باشند، باید بهجای آن از مسیر ماژول پردازنده استفاده کنید. (گزینه --processor-module-path را ببینید.) هنگامی که این موارد ناکافی باشند، ممکن است نیاز به انجام پیکربندیهای بیشتری بر روی محیط زمان اجرا باشد. این کار میتواند به دو روش انجام گیرد:
- 1.
- اگر javac از طریق خط فرمان فراخوانی شود، میتوان با افزودن پیشوند -J به گزینه، آن را به زمان اجرای زیربنایی منتقل کرد.
- 2.
- میتوان مستقیماً یک نمونه از Java Virtual Machine را راهاندازی کرد و با استفاده از گزینههای خط فرمان و API، محیطی را پیکربندی نمود که در آن بتوان javac را از طریق یکی از APIs آن فراخوانی کرد..SH "کامپایل برای نسخههای پیشین پلتفرم (COMPILING FOR EARLIER RELEASES OF THE PLATFORM)"
javac میتواند کدی را که قرار است در سایر نسخههای پلتفرم استفاده شود، با استفاده از گزینهٔ --release، یا گزینههای --source/-source و --target/-target، به همراه گزینههای اضافی برای تعیین کلاسهای پلتفرم کامپایل کند.
بسته به نسخهٔ پلتفرم مورد نظر، محدودیتهایی در استفاده از برخی گزینهها وجود دارد.
- •
- هنگام کامپایل برای JDK 8 و نسخههای پیشین، نمیتوانید از هیچ گزینهای که برای استفاده با سامانهٔ ماژول در نظر گرفته شده است استفاده کنید. این شامل تمام گزینههای زیر است:
- •
- --module-source-path، --upgrade-module-path، --system، --module-path، --add-modules، --add-exports، --add-opens، --add-reads، --limit-modules، --patch-module
اگر از گزینههای --source/-source یا --target/-target استفاده میکنید، باید کلاسهای مناسب پلتفرم را نیز با استفاده از خانوادهٔ گزینههای boot class path تنظیم نمایید.
- •
- هنگام کامپایل برای JDK 9 و نسخههای پس از آن، نمیتوانید از هیچ گزینهای که برای پیکربندی boot class path در نظر گرفته شده است استفاده کنید. این شامل تمام گزینههای زیر است:
- •
- -Xbootclasspath/p:، -Xbootclasspath، -Xbootclasspath/a:، -endorseddirs، -Djava.endorsed.dirs، -extdirs، -Djava.ext.dirs، -profile
اگر از گزینههای --source/-source یا --target/-target استفاده میکنید، باید کلاسهای مناسب پلتفرم را نیز با استفاده از گزینهٔ --system برای مشخص کردن مکان یک نسخهٔ نصبشدهٔ مناسب از JDK تنظیم نمایید.
هنگام استفاده از گزینهٔ --release، تنها APIهای مستند و پشتیبانیشده برای آن نسخه قابل استفاده هستند؛ شما نمیتوانید از هیچ گزینهای برای شکستن کپسولهسازی جهت دسترسی به کلاسهای داخلی استفاده کنید.
رابطهای برنامهنویسی (APIS)
کامپایلر javac را میتوان با استفاده از یک API به سه روش مختلف فراخوانی کرد:
- Java Compiler API
- این روش منعطفترین راه را برای فراخوانی کامپایلر فراهم میکند، از جمله امکان کامپایل فایلهای منبع ارائهشده در بافرهای حافظه یا سایر سیستمهای فایل غیر استاندارد.
- ToolProvider API
- یک ToolProvider برای javac را میتوان با فراخوانی ToolProvider.findFirst("javac") به دست آورد. این فراخوانی شیئی با قابلیتهای معادل ابزار خط فرمان برمیگرداند.
نکته: این API نباید با API همنام در بستهٔ javax.tools اشتباه گرفته شود.
- javac Legacy API
- این API صرفاً برای سازگاری عقبرو حفظ شده است. تمام کدهای جدید باید از Java Compiler API یا ToolProvider API استفاده کنند.
نکته: تمام کلاسها و متدهای دیگر موجود در بستههایی با نامهایی که با com.sun.tools.javac شروع میشوند (زیربستههای com.sun.tools.javac) کاملاً داخلی بوده و در هر زمانی ممکن است تغییر کنند..SH "مثالهایی از استفاده از کلیدهای -XLINT (EXAMPLES OF USING -XLINT KEYS)"
- cast
- درباره تبدیل نوعهای (cast) غیرضروری و زائد هشدار میدهد، برای نمونه:
String s = (String) "Hello!"
- classfile
- درباره مسائل مربوط به محتوای فایلهای کلاس (class file) هشدار میدهد.
- deprecation
- درباره استفاده از موارد منسوخشده (deprecated) هشدار میدهد. برای نمونه:
-
java.util.Date myDate = new java.util.Date(); int currentDay = myDate.getDay();
متد java.util.Date.getDay از زمان JDK 1.1 منسوخ شده است.
- dep-ann
- درباره مواردی که با توضیح جاواداک @deprecated مستند شدهاند، اما یادداشت (annotation) @Deprecated را ندارند هشدار میدهد، برای نمونه:
-
/** * @deprecated As of Java SE 7, replaced by {@link #newMethod()} */ public static void deprecatedMethod() { } public static void newMethod() { }
- divzero
- درباره تقسیم بر عدد صحیح ثابت 0 هشدار میدهد، برای نمونه:
int divideByZero = 42 / 0;
- empty
- درباره دستورهای خالی پس از عبارتهای if هشدار میدهد، برای نمونه:
-
class E { void m() { if (true) ; } }
- fallthrough
- بلوکهای switch را برای یافتن موارد گذر (fall-through cases) بررسی کرده و برای هر مورد یافتشده یک پیام هشدار صادر میکند. موارد گذر، مواردی در یک بلوک switch (به جز آخرین مورد در بلوک) هستند که کد آنها شامل دستور break نیست، که اجازه میدهد اجرای کد از آن مورد به مورد بعدی سرازیر (fall through) شود. برای نمونه، کد پس از برچسب case 1 در این بلوک switch به یک دستور break ختم نمیشود:
-
switch (x) { case 1: System.out.println("1"); // No break statement here. case 2: System.out.println("2"); }
اگر هنگام کامپایل این کد از گزینه -Xlint:fallthrough استفاده شده باشد، کامپایلر هشداری درباره احتمال سرازیر شدن به case بعدی، همراه با شماره خط case مورد نظر صادر میکند.
- finally
- درباره بندهای finally که نمیتوانند بهطور عادی خاتمه یابند هشدار میدهد، برای نمونه:
-
public static int m() { try { throw new NullPointerException(); } catch (NullPointerException(); { System.err.println("Caught NullPointerException."); return 1; } finally { return 0; } }
کامپایلر برای بلوک finally در این مثال هشداری تولید میکند. هنگامی که این متد int فراخوانی میشود، مقدار 0 را برمیگرداند. یک بلوک finally زمانی اجرا میشود که بلوک try خارج شود. در این مثال، هنگامی که کنترل به بلوک catch منتقل میشود، متد int خارج میشود. با این وجود، بلوک finally باید اجرا شود، بنابراین اجرا میشود، حتی اگر کنترل به خارج از متد منتقل شده باشد.
- options
- درباره مسائل مربوط به استفاده از گزینههای خط فرمان هشدار میدهد. بخش Compiling for Earlier Releases of the Platform را ببینید.
- overrides
- درباره مسائل مربوط به بازنویسی متدها (method overrides) هشدار میدهد. برای نمونه، دو کلاس زیر را در نظر بگیرید:
-
public class ClassWithVarargsMethod { void varargsMethod(String... s) { } } public class ClassWithOverridingMethod extends ClassWithVarargsMethod { @Override void varargsMethod(String[] s) { } }
کامپایلر هشداری مشابه زیر تولید میکند:
-
warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod overrides varargsMethod(String...) in ClassWithVarargsMethod; overriding method is missing '...'
هنگامی که کامپایلر با یک متد varargs مواجه میشود، پارامتر رسمی varargs را به یک آرایه تبدیل میکند. در متد ClassWithVarargsMethod.varargsMethod، کامپایلر پارامتر رسمی varargs یعنی String... s را به پارامتر رسمی String[] s ترجمه میکند؛ آرایهای که با پارامتر رسمی متد ClassWithOverridingMethod.varargsMethod مطابقت دارد. در نتیجه، این مثال کامپایل میشود.
- path
- درباره عناصر نامعتبر مسیر و دایرکتوریهای ناموجود مسیر در خط فرمان (با توجه به class path، source path و سایر مسیرها) هشدار میدهد. چنین هشدارهایی را نمیتوان با یادداشت @SuppressWarnings نادیده گرفت. برای نمونه:
- •
- لینوکس و macOS: javac -Xlint:path -classpath /nonexistentpath Example.java.IP • 2 ویندوز: javac -Xlint:path -classpath C:\nonexistentpath Example.java
- processing
- درباره مسائل مربوط به پردازش حاشیهنویسیها (annotation processing) هشدار میدهد. کامپایلر این هشدار را زمانی صادر میکند که کلاسی دارای یک حاشیهنویسی باشد، و شما از یک پردازشگر حاشیهنویسی استفاده کنید که نمیتواند آن نوع حاشیهنویسی را مدیریت کند. برای نمونه، مورد زیر یک پردازشگر حاشیهنویسی ساده است:
فایل منبع AnnoProc.java:
-
import java.util.*; import javax.annotation.processing.*; import javax.lang.model.*; import javax.lang.model.element.*; @SupportedAnnotationTypes("NotAnno") public class AnnoProc extends AbstractProcessor { public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){ return true; } public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } }
فایل منبع AnnosWithoutProcessors.java:
-
@interface Anno { } @Anno class AnnosWithoutProcessors { }
دستورهای زیر پردازشگر حاشیهنویسی AnnoProc را کامپایل کرده و سپس این پردازشگر حاشیهنویسی را روی فایل منبع AnnosWithoutProcessors.java اجرا میکنند:
-
javac AnnoProc.java javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java
هنگامی که کامپایلر پردازشگر حاشیهنویسی را روی فایل منبع AnnosWithoutProcessors.java اجرا میکند، هشدار زیر را صادر میکند:
-
warning: [processing] No processor claimed any of these annotations: Anno
برای رفع این مشکل، میتوانید حاشیهنویسی تعریفشده و استفادهشده در کلاس AnnosWithoutProcessors را از Anno به NotAnno تغییر نام دهید.
- rawtypes
- درباره عملیاتهای بررسینشده روی نوعهای خام (raw types) هشدار میدهد. عبارت زیر یک هشدار rawtypes ایجاد میکند:
void countElements(List l) { ... }
مثال زیر یک هشدار rawtypes ایجاد نمیکند:
void countElements(List<?> l) { ... }
نوع List یک نوع خام است. با این حال، List<?> یک نوع پارامتریشده با نویسه عام نامحدود (unbounded wildcard) است. از آنجا که List یک رابط (interface) پارامتریشده است، همواره آرگومان نوع آن را مشخص کنید. در این مثال، آرگومان صوری List با یک نویسه عام نامحدود (?) به عنوان پارامتر نوع صوری آن مشخص شده است، به این معنی که متد countElements میتواند هرگونه نمونهسازی از رابط List را بپذیرد.
- serial
- درباره تعریفنشدن serialVersionUID در کلاسهای سریالپذیر (serializable) هشدار میدهد. برای نمونه:
-
public class PersistentTime implements Serializable { private Date time; public PersistentTime() { time = Calendar.getInstance().getTime(); } public Date getTime() { return time; } }
کامپایلر هشدار زیر را صادر میکند:
-
warning: [serial] serializable class PersistentTime has no definition of serialVersionUID
اگر یک کلاس سریالپذیر فیلدی به نام serialVersionUID را به طور صریح اعلان نکند، محیط زمان اجرای سریالسازی بر اساس جنبههای مختلف کلاس، همانطور که در Java Object Serialization Specification شرح داده شده است، یک مقدار پیشفرض serialVersionUID را برای آن کلاس محاسبه میکند. با این حال، اکیداً توصیه میشود که تمام کلاسهای سریالپذیر مقادیر serialVersionUID را به طور صریح اعلان کنند، زیرا فرآیند پیشفرض محاسبه مقادیر serialVersionUID به شدت به جزئیات کلاس که ممکن است بسته به پیادهسازیهای کامپایلر تفاوت داشته باشد، وابسته و حساس است. در نتیجه، این امر ممکن است در طول واسریالسازی (deserialization) خطاهای پیشبینینشده InvalidClassExceptions ایجاد کند. برای تضمین یک مقدار serialVersionUID سازگار میان پیادهسازیهای مختلف کامپایلر Java، یک کلاس سریالپذیر باید به طور صریح یک مقدار serialVersionUID اعلان کند.
- static
- درباره مسائل مربوط به استفاده از متغیرهای ایستا (static)، برای نمونه هشدار میدهد:
-
class XLintStatic { static void m1() { } void m2() { this.m1(); } }
کامپایلر هشدار زیر را صادر میکند:
-
warning: [static] static method should be qualified by type name, XLintStatic, instead of by an expression
برای رفع این مشکل، میتوانید متد static یعنی m1 را به صورت زیر فراخوانی کنید:
XLintStatic.m1();
همچنین، میتوانید کلیدواژه static را از اعلان متد m1 حذف کنید.
- this-escape
- درباره نشت
دادن this توسط
سازندهها
پیش از
مقداردهی
اولیه
زیرکلاس
هشدار
میدهد.
برای
نمونه، این
کلاس:
public class MyClass { public MyClass() { System.out.println(this.hashCode()); } }
هشدار زیر را تولید میکند:
-
MyClass.java:3: warning: [this-escape] possible 'this' escape before subclass is fully initialized System.out.println(this.hashCode()); ^
هشدار فرار 'this' زمانی صادر میشود که یک سازنده کاری انجام دهد که ممکن است باعث فراخوانی متدی از یک زیرکلاس پیش از بازگشت سازنده شود. در چنین مواردی متد زیرکلاس روی نمونهای که هنوز مقداردهی اولیه آن کامل نشده است عمل خواهد کرد. در مثال بالا، اگر زیرکلاسی از MyClass متد hashCode() را جهت استفاده از فیلدهای خودش بازنویسی کند، در صورت فراخوانی به شکلی که نشان داده شده، به احتمال زیاد نتیجه نادرستی تولید خواهد کرد.
هشدارها
تنها در
صورتی صادر
میشوند که
امکان وجود
زیرکلاسی
خارج از
ماژول فعلی
(یا بسته، در
صورت نبود
ماژول) در
حال
کامپایل
وجود داشته
باشد.
بنابراین،
برای
نمونه،
سازندهها
در
کلاسهای final
و غیر public
هشدار
تولید
نمیکنند.
- try
- درباره مشکلات مربوط به استفاده از بلوکهای try، از جمله عبارتهای try-with-resources هشدار میدهد. برای نمونه، برای عبارت زیر هشداری ایجاد میشود زیرا منبع ac اعلانشده در بلوک try استفاده نشده است:
-
try ( AutoCloseable ac = getResource() ) { // do nothing}
- unchecked
- جزئیات بیشتری درباره هشدارهای تبدیل بررسینشده (unchecked conversion) که توسط Java Language Specification الزامی شدهاند ارائه میدهد؛ برای نمونه:
-
List l = new ArrayList<Number>(); List<String> ls = l; // unchecked warning
در طول پاکسازی نوع (type erasure)، نوعهای ArrayList<Number> و List<String> به ترتیب به ArrayList و List تبدیل میشوند.
دستور ls دارای نوع پارامتری List<String> است. هنگامی که List مورد اشاره توسط l به ls انتساب مییابد، کامپایلر یک هشدار unchecked صادر میکند. در زمان کامپایل، کامپایلر و JVM نمیتوانند تشخیص دهند که آیا l به نوع List<String> اشاره دارد یا خیر. در این مورد، l به نوع List<String> اشاره نمیکند. در نتیجه، آلودگی هیپ (heap pollution) رخ میدهد.
وضعیت آلودگی هیپ زمانی رخ میدهد که شیء List با نام l، که نوع ایستای آن List<Number> است، به شیء List دیگری به نام ls که نوع ایستای متفاوتی یعنی List<String> دارد، منتسب شود. با این وجود، کامپایلر همچنان این انتساب را مجاز میداند. کامپایلر باید این انتساب را مجاز بداند تا سازگاری با گذشته (backward compatibility) با نسخههایی از Java SE که از generics پشتیبانی نمیکردند حفظ شود. به دلیل پاکسازی نوع، هر دو نوع List<Number> و List<String> به List تبدیل میشوند. در نتیجه، کامپایلر انتساب شیء l را که نوع خامی (raw type) از List دارد، به شیء ls مجاز میشمارد.
- varargs
- درباره استفاده ناامن از متدهای با تعداد آرگومان متغیر (varargs)، بهویژه متدهایی که شامل آرگومانهای غیرقابلتحقق (non-reifiable) هستند، هشدار میدهد؛ برای نمونه:
-
public class ArrayBuilder { public static <T> void addToList (List<T> listArg, T... elements) { for (T x : elements) { listArg.add(x); } } }
یک نوع غیرقابلتحقق نوعی است که اطلاعات نوع آن در زمان اجرا (runtime) بهطور کامل در دسترس نیست.
کامپایلر هشدار زیر را برای تعریف متد ArrayBuilder.addToList صادر میکند:
-
warning: [varargs] Possible heap pollution from parameterized vararg type T
هنگامی که کامپایلر با یک متد varargs مواجه میشود، پارامتر صوری varargs را به یک آرایه تبدیل میکند. با این حال، زبان برنامهنویسی Java ساخت آرایههایی از نوعهای پارامتری را مجاز نمیداند. در متد ArrayBuilder.addToList، کامپایلر پارامتر صوری varargs به نام T... elements را به پارامتر صوری آرایهایِ T[] elements تبدیل میکند. اما به دلیل پاکسازی نوع، کامپایلر پارامتر صوری varargs را به Object[] elements تبدیل مینماید. در نتیجه، احتمال وقوع آلودگی هیپ وجود دارد.
| 2023 | JDK 21 |