| JAVAC(1) | JDK Commands | JAVAC(1) |
نام (NAME)
javac - خواندن اعلانهای جاوا و کامپایل آنها به فایلهای کلاس
خلاصه دستور (SYNOPSIS)
javac [options] [sourcefiles-or-classnames]
- options
- گزینههای خط فرمان.
- sourcefiles-or-classnames
- فایلهای منبع برای کامپایل (برای مثال، Shape.java) یا نام کلاسهای از پیش کامپایلشده برای پردازش حاشیهنویسیها (برای مثال، geometry.MyShape).
توضیحات (DESCRIPTION)
دستور javac فایلهای منبعی را که حاوی اعلانهای ماژول، بسته و نوع نوشتهشده به زبان برنامهنویسی جاوا هستند میخواند، و آنها را به فایلهای کلاس که روی ماشین مجازی جاوا اجرا میشوند کامپایل میکند.
دستور javac همچنین میتواند حاشیهنویسیها را پردازش کند که در فایلهای منبع و کلاسهای جاوا قرار دارند.
فایلهای منبع باید پسوند نام فایل .java داشته باشند. فایلهای کلاس دارای پسوند نام فایل .class هستند. بهطور معمول هم فایلهای منبع و هم فایلهای کلاس نامهایی دارند که محتوای آنها را مشخص میکند. برای مثال، کلاسی به نام Shape در یک فایل منبع به نام Shape.java اعلان میشود و در یک فایل کلاس با نام Shape.class کامپایل خواهد شد.
دو روش برای مشخص کردن فایلهای منبع برای javac وجود دارد:
- •
- برای تعداد کمی از فایلهای منبع، میتوانید نام فایلهای آنها را در خط فرمان فهرست کنید.
- •
- برای تعداد زیادی از فایلهای منبع، میتوانید از گزینهٔ @filename در خط فرمان استفاده کنید تا یک فایل آرگومان را مشخص نمایید که نامهای فایلها در آن فهرست شده است. برای شرح این گزینه به Standard Options و برای شرح فایلهای آرگومان javac به Command-Line Argument Files مراجعه کنید.
ترتیب فایلهای منبع مشخصشده در خط فرمان یا در یک فایل آرگومان اهمیتی ندارد. javac فایلها را با یکدیگر، بهعنوان یک گروه، کامپایل میکند و وابستگیهای میان اعلانها در فایلهای منبع گوناگون را بهطور خودکار رفع خواهد کرد.
javac انتظار دارد که فایلهای منبع در یک یا چند سلسلهمراتب دایرکتوری در سیستم فایل سازماندهی شده باشند، همانگونه که در Arrangement of Source Code شرح داده شده است.
برای کامپایل یک فایل منبع، javac باید اعلان هر کلاس یا رابطی را که توسط کد موجود در فایل منبع استفاده، گسترش داده شده، یا پیادهسازی شده است بیابد. این کار به javac اجازه میدهد بررسی کند که آیا کد، حق دسترسی به آن کلاسها و رابطها را دارد یا خیر. بهجای مشخص کردن صریح فایلهای منبع آن کلاسها و رابطها، میتوانید از گزینههای خط فرمان استفاده کنید تا به javac بگویید کجا به دنبال فایلهای منبع آنها جستجو کند. اگر پیشتر آن فایلهای منبع را کامپایل کردهاید، میتوانید از گزینهها استفاده کنید تا به javac بگویید کجا به دنبال فایلهای کلاس متناظر بگردد. این گزینهها، که همگی نامهایی ختمشده به “path” دارند، در Standard Options، و با جزئیات بیشتر در Configuring a Compilation و Searching for Module, Package and Type Declarations توضیح داده شدهاند.
بهطور پیشفرض، javac هر فایل منبع را به یک فایل کلاس در همان دایرکتوریِ فایل منبع کامپایل میکند. با این حال، توصیه میشود یک دایرکتوری مقصد جداگانه را با گزینهٔ -d مشخص کنید.
گزینهها و متغیرهای محیطی خط فرمان نیز نحوهٔ انجام وظایف مختلف توسط javac را کنترل میکنند:
- •
- کامپایل کد برای اجرا روی نگارشهای قدیمیتر JDK.
- •
- کامپایل کد برای اجرا زیر نظر یک اشکالزدا (debugger).
- •
- بررسی اشکالات نگارشی و سبک کدنویسی در کد منبع جاوا.
- •
- بررسی مشکلات موجود در یادداشتهای 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 را رونویسی (جایگزین) میکند.
نکته: این گزینه تنها هنگام کامپایل برای نسخههای پیش از 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
- دایرکتوری مقصد (یا دایرکتوری خروجی کلاس) را برای فایلهای کلاس تعیین میکند. اگر یک کلاس بخشی از یک بسته (package) باشد، javac فایل کلاس را در زیردایرکتوری متناسب با نام ماژول (در صورت وجود) و نام بسته قرار میدهد. اگر دایرکتوری و زیردایرکتوریهای لازم از قبل وجود نداشته باشند، ایجاد خواهند شد.
اگر گزینهٔ -d مشخص نشود، javac هر فایل کلاس را در همان دایرکتوری قرار میدهد که فایل منبع مولد آن در آن قرار دارد.
به جز مواردی که کد برای چندین ماژول کامپایل میشود، محتویات دایرکتوری خروجی کلاس در یک سلسلهمراتب بستهای سازماندهی میشوند. هنگام کامپایل کد برای چندین ماژول، محتویات دایرکتوری خروجی در یک سلسلهمراتب ماژولی سازماندهی میشوند؛ بهطوریکه محتویات هر ماژول در یک زیردایرکتوری جداگانه قرار میگیرد و هر کدام در یک سلسلهمراتب بستهای سازمان مییابند.
نکته: هنگام کامپایل کد برای یک یا چند ماژول، دایرکتوری خروجی کلاس هنگام جستوجو برای کلاسهای از پیش کامپایلشده بهطور خودکار بررسی میشود. هنگامی که برای ماژولها کامپایل صورت نمیگیرد، برای حفظ سازگاری با گذشته، دایرکتوری بهطور خودکار برای کلاسهای از پیش کامپایلشده بررسی نمیشود؛ از این رو توصیه میشود دایرکتوری خروجی کلاس را با استفاده از گزینهٔ --class-path یا یکی از اشکال جایگزین آن، به عنوان یکی از مکانهای مسیر کلاس کاربر مشخص کنید.
- -deprecation
- توضیحی از هر بار استفاده یا رونویسی (override) از یک عضو یا کلاس منسوخشده (deprecated) را نشان میدهد. بدون گزینهٔ -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
- مکان افزونههای (extensions) نصبشده را جایگزین میکند. directories فهرستی از دایرکتوریها است که با جداکنندهٔ مسیر پلتفرم (; در Windows، و در غیر این صورت :) جدا شدهاند. تمام فایلهای JAR موجود در دایرکتوریهای مشخصشده برای یافتن فایلهای کلاس جستوجو میشوند. همهٔ فایلهای JAR یافتشده بخشی از مسیر کلاس خواهند شد.
اگر برای نسخهای از پلتفرم کامپایل میکنید که از سازوکار افزونه (Extension Mechanism) پشتیبانی میکند، این گزینه دایرکتوریهای حاوی کلاسهای افزونه را مشخص میکند. بخش [Compiling for Other Releases of the Platform] را ببینید.
نکته: این گزینه تنها هنگام کامپایل برای نسخههای پیش از JDK 9 قابل استفاده است. در صورت لزوم، برای جزئیات به توضیحات --release، -source یا -target مراجعه کنید.
- -g
- تمامی اطلاعات اشکالزدایی، از جمله متغیرهای محلی را تولید میکند. بهطور پیشفرض، فقط اطلاعات شمارهٔ خط و فایل منبع تولید میشود.
- -g:[lines, vars, source]
- تنها آن دسته از اطلاعات اشکالزدایی را تولید میکند که با فهرست کلیدواژههای جداشده با ویرگول مشخص شدهاند. کلیدواژههای معتبر عبارتند از:
- lines
- اطلاعات اشکالزدایی شمارهٔ خط.
- vars
- اطلاعات اشکالزدایی متغیر محلی.
- -g:none
- اطلاعات اشکالزدایی تولید نمیکند.
- -h directory
- محل قرارگیری فایلهای سرایند محلی (native) تولیدشده را مشخص میکند.
هنگامی که این گزینه را مشخص میکنید، یک فایل سرایند محلی برای هر کلاسی که شامل متدهای محلی است یا دارای یک یا چند ثابت حاشیهنویسیشده با حاشیهنویسی 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 را به سیستم زمان اجرا (runtime) منتقل میکند، که در آن 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 از Reflection API بتواند آنها را بازیابی کند.
- -proc:[none, only]
- انجام پردازش حاشیهنویسی و کامپایل را کنترل میکند. -proc:none بدان معناست که کامپایل بدون پردازش حاشیهنویسی انجام میشود. -proc:only بدان معناست که تنها پردازش حاشیهنویسی، بدون هیچگونه کامپایل بعدی، انجام میشود.
- -processor class1[,class2,class3...]
- نامهای پردازشگرهای حاشیهنویسی برای اجرا. این کار فرایند پیشفرض شناسایی را دور میزند.
- --processor-module-path path
- مسیر ماژول مورد استفاده برای یافتن پردازشگرهای حاشیهنویسی را مشخص میکند.
- --processor-path path یا -processorpath path
- محل یافتن پردازشگرهای حاشیهنویسی را مشخص میکند. اگر از این گزینه استفاده نشود، مسیر کلاس (class path) برای یافتن پردازشگرها جستجو میشود.
- -profile profile
- بررسی میکند که API مورد استفاده در پروفایل مشخصشده موجود باشد.
نکته: این مورد تنها هنگام کامپایل برای نگارشهای پیش از JDK 9 قابل استفاده است. در صورت لزوم، برای جزئیات به توضیحات در --release، -source یا -target مراجعه کنید.
- --release 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 برای انتشار مشخصشده Java SE کامپایل میکند. مقادیر پشتیبانیشده برای release عبارتند از انتشار کنونی Java SE و تعداد محدودی از انتشارهای پیشین، که جزئیات آن در راهنمای خط فرمان آمده است.
اگر این گزینه مشخص نشود، پیشفرض این است که کد منبع مطابق با قوانین زبان برنامهنویسی Java برای انتشار کنونی Java SE کامپایل شود.
- --source-path path یا -sourcepath path
- محل یافتن فایلهای منبع را مشخص میکند. بهجز هنگام کامپایل همزمان چندین ماژول، این مسیر کد منبع است که برای جستجوی تعاریف کلاس (class) یا رابط (interface) استفاده میشود.
نکته: کلاسهای یافتشده از طریق مسیر کلاس (class path) ممکن است در صورتی که فایلهای منبع آنها نیز یافت شوند، مجدداً کامپایل گردند. به Searching for Module, Package and Type Declarations مراجعه کنید.
- --system jdk | none
- مکان ماژولهای سیستم را بازنویسی میکند.
- --target release یا -target release
- فایلهای class مناسب برای انتشار مشخصشده Java SE را تولید میکند. مقادیر پشتیبانیشده برای release عبارتند از انتشار کنونی Java SE و تعداد محدودی از انتشارهای پیشین، که جزئیات آن در راهنمای خط فرمان آمده است.
نکته: انتشار مقصد (target release) باید برابر یا بالاتر از انتشار مبدأ (source release) باشد. (به --source مراجعه کنید.)
- --upgrade-module-path path
- مکان ماژولهای قابل ارتقا را بازنویسی میکند.
- -verbose
- پیامهایی دربارهٔ عملیات کامپایلر صادر میکند. پیامها شامل اطلاعات مربوط به هر کلاس بارگذاریشده و هر فایل منبع کامپایلشده است.
- --version یا -version
- اطلاعات نسخه را چاپ میکند.
- -Werror
- در صورت بروز هشدار، فرآیند کامپایل را خاتمه میدهد.
گزینههای اضافی (Extra Options)
- --add-exports module/package=other-module(,other-module)*
- بستهای را مشخص میکند تا از ماژول تعریفکنندهاش به ماژولهای اضافی، یا در صورتی که مقدار other-module برابر با ALL-UNNAMED باشد به تمام ماژولهای بینام (unnamed modules)، صادرشده (exported) در نظر گرفته شود.
- --add-reads module=other-module(,other-module)*
- ماژولهای اضافی را مشخص میکند تا بهعنوان نیازمندیهای یک ماژول دادهشده در نظر گرفته شوند.
- --default-module-for-created-files module-name
- در صورتی که هیچ ماژولی مشخص یا استنتاج نشده باشد، ماژول مقصد جایگزین (fallback) را برای فایلهای ایجادشده توسط پردازشگرهای حاشیهنویسی (annotation processors) مشخص میکند.
- -Djava.endorsed.dirs=dirs
- مکان مسیر استانداردهای تأییدشده (endorsed standards path) را بازنویسی میکند.
نکته: این گزینه فقط هنگام کامپایل برای انتشارهای قبل از JDK 9 قابل استفاده است. برحسب مورد، برای جزئیات به توضیحات در --release، -source یا -target مراجعه کنید.
- -Djava.ext.dirs=dirs
- مکان افزونههای نصبشده را بازنویسی میکند.
نکته: این گزینه فقط هنگام کامپایل برای انتشارهای قبل از JDK 9 قابل استفاده است. برحسب مورد، برای جزئیات به توضیحات در --release، -source یا -target مراجعه کنید.
- --patch-module module=path
- یک ماژول را با کلاسها و منابع موجود در فایلهای JAR یا دایرکتوریها بازنویسی کرده یا گسترش میدهد.
- -Xbootclasspath:path
- مکان فایلهای کلاس راهانداز (bootstrap class files) را بازنویسی میکند.
نکته: این گزینه فقط هنگام کامپایل برای انتشارهای قبل از JDK 9 قابل استفاده است. برحسب مورد، برای جزئیات به توضیحات در --release، -source یا -target مراجعه کنید.
- -Xbootclasspath/a:path
- یک پسوند به مسیر کلاس راهانداز (bootstrap class path) میافزاید.
نکته: این گزینه فقط هنگام کامپایل برای انتشارهای قبل از JDK 9 قابل استفاده است. برحسب مورد، برای جزئیات به توضیحات در --release، -source یا -target مراجعه کنید.
- -Xbootclasspath/p:path
- یک پیشوند به مسیر کلاس راهانداز (bootstrap class path) میافزاید.
نکته: این گزینه فقط هنگام کامپایل برای انتشارهای قبل از JDK 9 قابل استفاده است. برحسب مورد، برای جزئیات به توضیحات در --release، -source یا -target مراجعه کنید.
- -Xdiags:[compact, verbose]
- یک حالت عیبیابی را انتخاب میکند.
- -Xdoclint
- بررسیهای توصیهشده برای مشکلات موجود در کامنتهای javadoc را فعال میکند.
- -Xdoclint:(all|none|[-]group)[/access]
- گروههای خاصی از بررسیها را فعال یا غیرفعال میکند،
مقدار group میتواند یکی از موارد زیر باشد:
- •
- accessibility
- •
- html
- •
- missing
- •
- reference
- •
- syntax
متغیر access حداقل سطح دیداری (visibility) کلاسها و اعضایی را که گزینهٔ -Xdoclint بررسی میکند، مشخص میسازد. این متغیر میتواند یکی از مقادیر زیر باشد (به ترتیب از بیشترین به کمترین میزان دیداری):
- •
- public
- •
- protected
- •
- package
- •
- private
سطح دیداری پیشفرض access برابر با private است.
برای اطلاعات بیشتر دربارهٔ این گروههای بررسی، گزینهٔ -Xdoclint در دستور javadoc را ببینید. گزینهٔ -Xdoclint بهطور پیشفرض در دستور javac غیرفعال است.
برای مثال، گزینهٔ زیر کلاسها و اعضایی را (با تمام گروههای بررسی) که دارای سطح دسترسی protected و بالاتر هستند (که شامل protected و public میشود) بررسی میکند:
-Xdoclint:all/protected
گزینهٔ زیر تمام گروههای بررسی را برای همهٔ سطوح دسترسی فعال میکند، بهجز اینکه خطاهای HTML را برای کلاسها و اعضایی که دارای سطح دسترسی package و بالاتر هستند (که شامل package، protected و public میشود) بررسی نمیکند: -Xdoclint:all,-html/package
- -Xdoclint/package:[-]packages(,[-]package)*
- بررسیها را در بستههای مشخص فعال یا غیرفعال میکند. هر package یا نام کامل (qualified name) یک بسته است یا پیشوند نام بسته به همراه .*، که به تمام زیربستههای بسته دادهشده گسترش مییابد. هر package میتواند با یک خط تیره (-) شروع شود تا بررسیها برای یک یا چند بسته مشخص غیرفعال گردند.
- -Xlint
- همه هشدارهای توصیهشده را فعال میکند. در این نسخه، فعالسازی تمام هشدارهای موجود توصیه میشود.
- -Xlint:[-]key(,[-]key)*
- هشدارهایی را برای فعال یا غیرفعال شدن تعیین میکند که با ویرگول جدا میشوند. برای غیرفعال کردن هشدار مشخصشده، یک خط تیره (-) پیش از کلید قرار دهید.
مقادیر پشتیبانیشده برای key عبارتند از:
- •
- all: همه هشدارها را فعال میکند.
- •
- auxiliaryclass: درباره یک کلاس کمکی (auxiliary class) که در یک فایل مبدأ پنهان شده و در فایلهای دیگر استفاده شده است، هشدار میدهد.
- •
- cast: درباره استفاده از تبدیلهای نوع (cast) غیرضروری هشدار میدهد.
- •
- classfile: درباره مسائل مربوط به محتویات classfile هشدار میدهد.
- •
- deprecation: درباره استفاده از موارد منسوخشده (deprecated) هشدار میدهد.
- •
- dep-ann: درباره مواردی که در javadoc به عنوان منسوخ مشخص شدهاند اما فاقد یادداشت @Deprecated هستند، هشدار میدهد.
- •
- divzero: درباره تقسیم بر عدد صحیح ثابت 0 هشدار میدهد.
- •
- empty: درباره عبارت خالی پس از دستور if هشدار میدهد.
- •
- exports: درباره مسائل مربوط به صادرات ماژول (module exports) هشدار میدهد.
- •
- fallthrough: درباره افتادن (fall-through) از یک حالت دستور switch به حالت بعدی هشدار میدهد.
- •
- finally: درباره بندهای finally که بهطور عادی خاتمه نمییابند هشدار میدهد.
- •
- module: درباره مسائل مرتبط با سیستم ماژول هشدار میدهد.
- •
- opens: درباره مسائل مربوط به باز کردن ماژول (module opens) هشدار میدهد.
- •
- options: درباره مسائل مربوط به استفاده از گزینههای خط فرمان هشدار میدهد.
- •
- overloads: درباره مسائل مربوط به چندریختی متدها (method overloads) هشدار میدهد.
- •
- overrides: درباره مسائل مربوط به بازنویسی متدها (method overrides) هشدار میدهد.
- •
- path: درباره عناصر نامعتبر مسیر در خط فرمان هشدار میدهد.
- •
- processing: درباره مسائل مربوط به پردازش یادداشتها (annotation processing) هشدار میدهد.
- •
- rawtypes: درباره استفاده از انواع خام (raw types) هشدار میدهد.
- •
- removal: درباره استفاده از یک API که برای حذف علامتگذاری شده است هشدار میدهد.
- •
- requires-automatic: به توسعهدهندگان درباره استفاده از ماژولهای خودکار (automatic modules) در بندهای requires هشدار میدهد.
- •
- requires-transitive-automatic: درباره ماژولهای خودکار در requires transitive هشدار میدهد.
- •
- serial: درباره کلاسهای قابلسریالسازی (serializable) که شناسه نسخه سریالی ارائه نمیدهند هشدار میدهد. همچنین درباره دسترسی به اعضای غیرعمومی از یک عنصر قابلسریالسازی هشدار میدهد.
- •
- static: درباره دسترسی به یک عضو ایستا (static) از طریق یک نمونه شیء هشدار میدهد.
- •
- try: درباره مسائل مربوط به استفاده از بلوکهای try (یعنی try-with-resources) هشدار میدهد.
- •
- unchecked: درباره عملیاتهای بررسینشده (unchecked) هشدار میدهد.
- •
- varargs: درباره متدهای بالقوه ناامن vararg هشدار میدهد.
- •
- none: همه هشدارها را غیرفعال میکند.
بخش 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 حاوی یادداشتها (annotations) باشد. این گزینه در صورتی که package-info.java فقط شامل توضیحات (comments) باشد، فایل package-info.class تولید نمیکند.
نکته: ممکن است یک فایل package-info.class تولید شود اما در صورتی که تمام یادداشتهای موجود در فایل package-info.java دارای RetentionPolicy.SOURCE باشند، خالی خواهد بود.
- nonempty
- تنها در صورتی یک فایل package-info.class تولید میکند که package-info.java شامل یادداشتهایی با RetentionPolicy.CLASS یا RetentionPolicy.RUNTIME باشد.
- -Xplugin:name args
- نام و آرگومانهای اختیاری را برای اجرای یک افزونه (plug-in) مشخص میکند. در صورت ارائه 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 : فایل مبدأ را میخواند. زمانی از -Xprefer:source استفاده کنید که میخواهید مطمئن شوید پردازندههای یادداشت میتوانند به یادداشتهای اعلانشده با سیاست نگهداری SOURCE دسترسی داشته باشند.
- -Xprint
- نمایشی متنی از نوعهای مشخصشده را برای اهداف اشکالزدایی چاپ میکند. این گزینه پردازش یادداشت یا کامپایل را انجام نمیدهد. قالب خروجی ممکن است تغییر کند.
- -XprintProcessorInfo
- اطلاعاتی درباره اینکه از پردازنده درخواست پردازش چه یادداشتهایی شده است را چاپ میکند.
- -XprintRounds
- اطلاعاتی را درباره دورهای اولیه و بعدی پردازش یادداشت چاپ میکند.
- -Xstdout filename
- پیامهای کامپایلر را به فایل مشخصشده ارسال میکند. بهطور پیشفرض، پیامهای کامپایلر به System.err ارسال میشوند.
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 با آرگومانی مواجه میشود که با علامت اَت (@) آغاز شده است، محتویات آن فایل را در فهرست آرگومانها باز میکند.
مثالهای استفاده از javac @filename
- فایل آرگومان تکی
- میتوانید از یک فایل آرگومان به نام argfile برای نگهداری تمام آرگومانهای javac استفاده کنید:
javac @argfile
این فایل آرگومان میتواند حاوی محتویات هر دو فایل نشاندادهشده در مثال زیر یعنی دو فایل آرگومان باشد.
- دو فایل آرگومان
- میتوانید دو فایل آرگومان ایجاد کنید: یکی برای گزینههای javac و دیگری برای نامهای فایلهای منبع. توجه داشته باشید که فهرستهای زیر هیچ نویسهٔ ادامهدهندهٔ خطی ندارند.
فایلی به نام options ایجاد کنید که حاوی موارد زیر باشد:
لینوکس و macOS:
-
-d classes -g -sourcepath /java/pubs/ws/1.3/src/share/classes
ویندوز:
-
-d classes -g -sourcepath C:\java\pubs\ws\1.3\src\share\classes
فایلی به نام classes ایجاد کنید که حاوی موارد زیر باشد:
-
MyClass1.java MyClass2.java MyClass3.java
سپس، دستور javac را به صورت زیر اجرا کنید:
javac @options @classes
- فایلهای آرگومان دارای مسیر
- فایلهای آرگومان میتوانند دارای مسیر باشند، اما هر نام فایلی درون این فایلها نسبت به دایرکتوری کاری جاری سنجیده میشود (نه نسبت به path1 یا path2):
javac @path1/options @path2/classes
در زبان Java، کلاسها و رابطها (interfaces) میتوانند در بستهها (packages) سازماندهی شوند، و بستهها نیز میتوانند در ماژولها قرار گیرند. javac انتظار دارد که چیدمان فیزیکی فایلهای منبع در دایرکتوریهای سیستمفایل، منعکسکننده سازماندهی کلاسها در بستهها، و بستهها در ماژولها باشد.
این یک قرارداد پذیرفتهشده گسترده است که نام ماژولها و بستهها با حروف کوچک و نام کلاسها با حروف بزرگ آغاز شود.
چیدمان کد منبع برای یک بسته
هنگامی که کلاسها و رابطها در یک بسته سازماندهی میشوند، آن بسته بهصورت یک دایرکتوری و هر زیربسته (subpackage) بهصورت یک زیردایرکتوری نمایش داده میشود.
برای نمونه:
- •
- بسته 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 (در سایر سیستمها) قرار داشته باشند.
پیکربندی کامپایل (CONFIGURING A COMPILATION)
این بخش نحوه پیکربندی javac را برای انجام یک کامپایل پایه شرح میدهد.
برای جزئیات بیشتر هنگام کامپایل برای نسخهای از پلتفرم که از ماژولها پشتیبانی میکند، به بخش Configuring the Module System مراجعه کنید.
فایلهای منبع
- •
- فایلهای منبع مورد نظر برای کامپایل را در خط فرمان مشخص کنید.
در صورت نبود خطای کامپایل، فایلهای کلاس متناظر در دایرکتوری خروجی قرار خواهند گرفت.
برخی سیستمها ممکن است مقداری را که میتوانید در خط فرمان وارد کنید محدود سازند؛ برای دور زدن این محدودیتها، میتوانید از فایلهای آرگومان (argument files) استفاده کنید.
هنگام کامپایل کدها برای ماژولها، همچنین میتوانید فایلهای منبع را بهصورت غیرمستقیم با استفاده از گزینه --module یا -m مشخص کنید.
دایرکتوری خروجی
- •
- از گزینه -d برای مشخص کردن یک دایرکتوری خروجی جهت قرار دادن فایلهای کلاس کامپایلشده استفاده کنید.
این دایرکتوری معمولاً در قالب یک سلسلهمراتب بستهها سازماندهی میشود، مگر اینکه کدهای منبع چندین ماژول را کامپایل کنید که در این صورت بهصورت یک سلسلهمراتب ماژولها سازماندهی خواهد شد.
پس از اتمام کامپایل، چنانچه یک یا چند ماژول را کامپایل کرده باشید، میتوانید دایرکتوری خروجی را در مسیر ماژول (module path) برای راهانداز (launcher) جاوا قرار دهید؛ در غیر این صورت، میتوانید دایرکتوری خروجی را در مسیر کلاس (class path) برای راهانداز جاوا تعیین کنید..SS کد از پیش کامپایلشده
کدی که قرار است کامپایل شود ممکن است به کتابخانههایی فراتر از آنچه توسط پلتفرم ارائه شده است ارجاع دهد. اگر چنین است، باید این کتابخانهها را در مسیر کلاس یا مسیر ماژول قرار دهید. اگر کد کتابخانه در یک ماژول قرار ندارد، آن را در مسیر کلاس بگذارید؛ اگر درون یک ماژول است، آن را در مسیر ماژول قرار دهید.
- •
- از گزینهٔ --class-path برای مشخص کردن کتابخانههایی که باید در مسیر کلاس قرار گیرند استفاده کنید. مکانها در مسیر کلاس باید در یک سلسلهمراتب بسته سازماندهی شوند. همچنین میتوانید از اشکال دیگر این گزینه استفاده کنید: -classpath یا -cp.
- •
- از گزینهٔ --module-path برای مشخص کردن کتابخانههایی که باید در مسیر ماژول قرار گیرند استفاده کنید. مکانها در مسیر ماژول باید ماژول یا دایرکتوریهایی از ماژولها باشند. همچنین میتوانید از شکل جایگزین این گزینه استفاده کنید: -p.
برای جزئیات بیشتر دربارهٔ نحوهٔ تغییر پیکربندی پیشفرض ماژولهای کتابخانهای، Configuring the Module System را ببینید.
نکته: گزینههای مربوط به مسیر کلاس و مسیر ماژول مانعةالجمع نیستند، اگرچه هنگام کامپایل کد برای یک یا چند ماژول، مشخص کردن مسیر کلاس مرسوم نیست.
فایلهای منبع اضافی
کدی که قرار است کامپایل شود ممکن است به انواعی در فایلهای منبع اضافی که در خط فرمان مشخص نشدهاند ارجاع دهد. اگر چنین است، باید آن فایلهای منبع را در مسیر منبع یا مسیر ماژول قرار دهید. تنها میتوانید یکی از این گزینهها را مشخص کنید: اگر کدی را برای یک ماژول کامپایل نمیکنید، یا تنها برای یک ماژول واحد کد کامپایل میکنید، از مسیر منبع استفاده کنید؛ اگر کد را برای چند ماژول کامپایل میکنید، از مسیر منبع ماژول بهره ببرید.
- •
- از گزینهٔ --source-path برای مشخص کردن مکانهای فایلهای منبع تکمیلی که ممکن است توسط javac خوانده شوند استفاده کنید. مکانها در مسیر منبع باید در یک سلسلهمراتب بسته سازماندهی شوند. همچنین میتوانید از شکل دیگر این گزینه استفاده کنید: -sourcepath.
- •
- از گزینهٔ --module-source-path یک یا چند بار برای مشخص کردن مکان فایلهای منبع اضافی در ماژولهای مختلف که ممکن است توسط javac خوانده شوند، یا هنگام کامپایل فایلهای منبع در چندین ماژول استفاده کنید. میتوانید مکانها را برای هر ماژول بهصورت جداگانه مشخص کنید، یا فایلهای منبع را طوری سازماندهی کنید که بتوانید تمام مکانها را بهطور یکجا تعیین نمایید. برای جزئیات بیشتر، The Module Source Path Option را ببینید.
اگر میخواهید بتوانید به انواع در فایلهای منبع اضافی ارجاع دهید اما مایل نیستید آنها کامپایل شوند، از گزینهٔ -implicit استفاده کنید.
نکته: اگر کدی را برای چندین ماژول کامپایل میکنید، همیشه باید مسیر منبع ماژول را مشخص نمایید، و تمام فایلهای منبع مشخصشده در خط فرمان باید درون یکی از دایرکتوریهای واقع در مسیر منبع ماژول یا زیردایرکتوریهای آن باشند.
مثال کامپایل چندین فایل منبع
این مثال فایلهای منبع 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
مثال تعیین مسیر کلاس کاربر
پس از ایجاد تغییر در یکی از فایلهای منبع در مثال قبلی، آن را دوباره کامپایل کنید:
لینوکس و 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 را تغییر دهید تا از یک ابزار بنر استفاده کند، آن ابزار نیز باید از طریق مسیر کلاس کاربر در دسترس باشد.
لینوکس و 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 استفاده کنید. این کار در صورتی مفید است که بخواهید اطمینان حاصل کنید کدی که کامپایل میکنید قادر است روی سیستمی با مجموعهٔ محدودی از ماژولهای نصبشده اجرا شود.
اگر میخواهید کپسولهسازی (encapsulation) را بشکنید و مشخص کنید که بستههای اضافی باید به عنوان صادرشده (exported) از یک ماژول در نظر گرفته شوند، از گزینهٔ --add-exports استفاده کنید. این کار ممکن است هنگام انجام آزمون جعبهسفید (white-box testing) مفید باشد؛ اتکا به دسترسی به API داخلی در کد محیط عملیاتی اکیداً توصیه نمیشود.
اگر میخواهید مشخص کنید که بستههای اضافی باید به عنوان نیازمندی توسط یک ماژول در نظر گرفته شوند، از گزینهٔ --add-reads استفاده کنید. این کار ممکن است هنگام انجام آزمون جعبهسفید مفید باشد؛ اتکا به دسترسی به API داخلی در کد محیط عملیاتی اکیداً توصیه نمیشود.
میتوانید با استفاده از گزینهٔ --patch-module محتوای اضافی را به درون هر ماژولی وصله کنید. برای جزئیات بیشتر به [Patching a Module] مراجعه کنید.
جستجوی اعلانهای ماژول، بسته و نوع (SEARCHING FOR MODULE, PACKAGE AND TYPE DECLARATIONS)
برای کامپایل یک فایل منبع، کامپایلر اغلب به اطلاعاتی دربارهٔ یک ماژول یا نوع (type) نیاز دارد، در حالی که اعلان آن در فایلهای منبعِ مشخصشده در خط فرمان وجود ندارد.
javac برای هر کلاس یا واسطی (interface) که در فایل منبع استفاده شده، گسترش یافته (extended)، یا پیادهسازی شده (implemented) است، به اطلاعات نوع نیاز دارد. این شامل کلاسها و واسطهایی نیز میشود که به صراحت در فایل منبع ذکر نشدهاند، اما اطلاعات را از طریق وراثت ارائه میدهند.
برای نمونه، هنگامی که یک زیرکلاس از 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 هر مکان در مسیر را به نوبت برای احتمال حضور فایل بررسی میکند. اولین رخداد از یک فایل خاص، هرگونه رخداد بعدی فایلهای همنام را سایهاندازی (پنهان) میکند. این سایهاندازی بر جستجو برای فایلهایی با نام متفاوت تأثیری نمیگذارد. این ویژگی هنگام جستجوی فایلهای منبع که ممکن است در مکانهای متفاوتی گروهبندی شده باشند—مانند کد اشتراکی، کد مختص پلتفرم و کد تولیدشده—میتواند بسیار کارآمد باشد. همچنین میتواند هنگام تزریق نسخههای جایگزین یک فایل کلاس به یک بسته، برای اشکالزدایی یا سایر دلایل ابزارسازی (instrumentation) مفید باشد. اما این کار میتواند خطرناک نیز باشد، مانند زمانی که نسخههای ناسازگار متفاوتی از یک کتابخانه در مسیر کلاس (class path) قرار میگیرند.
جستجوی مسیرهای ماژولمحور (Searching Module Oriented Paths)
پیش از پویش هر یک از مسیرهای ماژول برای اعلانهای بسته یا نوع، javac به صورت تنبل (lazy) مسیرها و مکانهای زیر را پویش میکند تا ماژولهایی را که در کامپایل استفاده خواهند شد مشخص کند:
- •
- مسیر منبع ماژول (گزینهٔ --module-source-path را ببینید)
- •
- مسیر ماژولهای ارتقاپذیر (گزینهٔ --upgrade-module-path را ببینید)
- •
- ماژولهای سامانه (گزینهٔ --system را ببینید)
- •
- مسیر ماژول کاربر (گزینهٔ --module-path را ببینید)
برای هر ماژول، اولین رخداد ماژول در طول پویش، هرگونه ظهور بعدی ماژولی با نام مشابه را کاملاً سایهاندازی (پنهان) میکند. در حین مکانیابی ماژولها، javac قادر است بستههای صادرشده توسط ماژول را تعیین کرده و به هر ماژول یک مسیر بستهمحور برای محتویات آن اختصاص دهد. برای هر ماژول که قبلاً کامپایل شده است، این مسیر معمولاً یک ورودی تکی برای یک دایرکتوری یا فایلی است که سلسلهمراتبی دایرکتوریمانند درونی فراهم میکند، مانند یک فایل JAR. بنابراین، هنگام جستجو برای نوعی که در بستهای قرار دارد که صادر شدن آن توسط یک ماژول مشخص است، javac میتواند اعلان را مستقیماً و به شکلی کارآمد پیدا کند.
جستجو برای اعلان یک ماژول (Searching for the Declaration of a Module)
اگر ماژول قبلاً کامپایل شده باشد، اعلان ماژول در فایلی به نام module-info.class در ریشهٔ سلسلهمراتب بسته برای محتوای ماژول قرار دارد.
اگر ماژول یکی از مواردی باشد که هماکنون در حال کامپایل شدن است، اعلان ماژول یا فایلی به نام module-info.class در ریشهٔ سلسلهمراتب بسته برای ماژول در دایرکتوری خروجی کلاسها خواهد بود، یا فایلی به نام module-info.java در یکی از مکانهای موجود در مسیر منبع یا مسیر منبع ماژول برای آن ماژول..SS "جستجوی اعلان یک نوع هنگامی که ارجاع در یک ماژول نیست"
هنگام جستجو برای نوعی که در کدی خارج از یک ماژول به آن ارجاع داده شده است، javac در مکانهای زیر جستجو خواهد کرد:
- •
- کلاسهای پلتفرم (یا نوعهای موجود در بستههای صادرشدهٔ ماژولهای پلتفرم) (این مورد تنها برای فایلهای کلاس کامپایلشده است.)
- •
- نوعهای موجود در بستههای صادرشدهٔ هر یک از ماژولهای موجود در مسیر ماژول (module path)، در صورت وجود. (این مورد تنها برای فایلهای کلاس کامپایلشده است.)
- •
- نوعهای موجود در بستههای روی مسیر کلاس (class path) و/یا مسیر منبع (source path):
- •
- اگر هر دو مشخص شده باشند، javac به دنبال فایلهای کلاس کامپایلشده در مسیر کلاس و فایلهای منبع در مسیر منبع میگردد.
- •
- اگر مسیر کلاس مشخص شده باشد اما مسیر منبع مشخص نشده باشد، javac به دنبال هر دو مورد، یعنی فایلهای کلاس کامپایلشده و فایلهای منبع در مسیر کلاس میگردد.
- •
- اگر مسیر کلاس مشخص نشده باشد، مقدار پیشفرض آن دایرکتوری جاری خواهد بود.
هنگام جستجوی یک نوع در مسیر کلاس و/یا مسیر منبع، اگر هم فایل کلاس کامپایلشده و هم فایل منبع یافت شوند، بهطور پیشفرض فایلی که اخیراً تغییر یافته استفاده خواهد شد. اگر فایل منبع جدیدتر باشد، کامپایل خواهد شد و ممکن است جایگزین هر نسخهٔ از قبل کامپایلشدهای از آن فایل شود. میتوانید از گزینهٔ -Xprefer برای لغو رفتار پیشفرض استفاده کنید.
جستجوی اعلان یک نوع هنگامی که ارجاع در یک ماژول است
هنگام جستجو برای نوعی که در کدِ درون یک ماژول به آن ارجاع داده شده است، javac اعلان ماژولِ دربرگیرنده را بررسی میکند تا مشخص کند آیا آن نوع در بستهای قرار دارد که از ماژول دیگری صادر شده و توسط ماژول دربرگیرنده خواندنی است یا خیر. در این صورت، javac بهسادگی و بهطور مستقیم به تعریف آن ماژول میرود تا تعریف نوع مورد نیاز را پیدا کند. مگر اینکه آن ماژول یکی دیگر از ماژولهای در حال کامپایل باشد، javac تنها به دنبال فایلهای کلاس کامپایلشده خواهد گشت. به عبارت دیگر، javac به دنبال فایلهای منبع در ماژولهای پلتفرم یا ماژولهای موجود در مسیر ماژول نخواهد گشت.
اگر نوع مورد ارجاع در ماژول خواندنی دیگری نباشد، javac ماژول در حال کامپایل را بررسی میکند تا اعلان آن نوع را بیابد. javac به دنبال اعلان نوع به صورت زیر خواهد گشت:
- •
- فایلهای منبع مشخصشده در خط فرمان یا در مسیر منبع (source path) یا مسیر منبع ماژول (module source path).
- •
- فایلهای از قبل کامپایلشده در دایرکتوری خروجی.
سلسلهمراتبهای دایرکتوری (DIRECTORY HIERARCHIES)
javac بهطور کلی فرض میکند که فایلهای منبع و فایلهای کلاس کامپایلشده در سلسلهمراتب دایرکتوریِ سیستم فایل، یا در نوعی فایل که از سلسلهمراتب دایرکتوری داخلی پشتیبانی میکند (مانند فایل JAR)، سازماندهی خواهند شد. سه نوع سلسلهمراتب مختلف پشتیبانی میشود: سلسلهمراتب بسته (package hierarchy)، سلسلهمراتب ماژول (module hierarchy)، و سلسلهمراتب منبع ماژول (module source hierarchy).
اگرچه javac در مورد سازماندهی کد منبع (فراتر از این انتظار که منبع در یک یا چند سلسلهمراتب بسته سازماندهی شود) رفتار نسبتاً منعطفی دارد و عموماً میتواند با ساختارهای تعیینشده توسط محیطهای توسعه و ابزارهای ساخت سازگار شود، اما ابزارهای جاوا بهطور کلی، و javac و راهانداز جاوا بهطور خاص، در رابطه با سازماندهی فایلهای کلاس کامپایلشده سختگیرتر هستند و آنها را بر حسب مورد، در سلسلهمراتبهای بسته یا سلسلهمراتبهای ماژول سازماندهی میکنند.
مکان این سلسلهمراتبها با گزینههای خط فرمان به javac مشخص میشود؛ گزینههایی که نام آنها معمولاً به «path» ختم میشود، مانند --source-path یا --class-path. همچنین به عنوان یک قاعده کلی، گزینههای مسیری که نام آنها شامل واژهٔ module است، مانند --module-path، برای مشخص کردن سلسلهمراتبهای ماژول به کار میروند، اگرچه برخی از گزینههای مسیر مرتبط با ماژول اجازه میدهند سلسلهمراتب بسته به ازای هر ماژول تعیین شود. تمام گزینههای مسیر دیگر برای تعیین سلسلهمراتبهای بسته استفاده میشوند.
سلسلهمراتب بسته (Package Hierarchy)
در یک سلسلهمراتب بسته، از دایرکتوریها و زیردایرکتوریها برای نمایش بخشهای تشکیلدهندهٔ نام بسته استفاده میشود، بهطوری که فایل منبع یا فایل کلاس کامپایلشده برای یک نوع به صورت فایلی با پسوند .java یا .class در تو در تو ترین دایرکتوری ذخیره میشود.
برای نمونه، در یک سلسلهمراتب بسته، فایل منبع برای کلاس com.example.MyClass در فایل com/example/MyClass.java ذخیره خواهد شد.
سلسلهمراتب ماژول (Module Hierarchy)
در یک سلسلهمراتب ماژول، سطح اول دایرکتوریها با نام ماژولهای موجود در سلسلهمراتب نامگذاری میشوند؛ درون هر یک از آن دایرکتوریها، محتویات ماژول در سلسلهمراتبهای بسته سازماندهی میشوند.
برای نمونه، در یک سلسلهمراتب ماژول، فایل کلاس کامپایلشده برای نوعی به نام com.example.MyClass در ماژولی به نام my.library در my.library/com/example/MyClass.class ذخیره خواهد شد.
دایرکتوریهای خروجی گوناگونی که توسط javac استفاده میشوند (دایرکتوری خروجی کلاس، دایرکتوری خروجی منبع، و دایرکتوری خروجی سرایند بومی/native header) هنگامی که چندین ماژول کامپایل میشوند، همگی در یک سلسلهمراتب ماژول سازماندهی خواهند شد.
سلسلهمراتب منبع ماژول (Module Source Hierarchy)
اگرچه منبع هر ماژول مجزا همیشه باید در یک سلسلهمراتب بسته سازماندهی شود، ممکن است گروهبندی این سلسلهمراتبها در یک سلسلهمراتب منبع ماژول راحتتر باشد. این ساختار شبیه به یک سلسلهمراتب ماژول است، با این تفاوت که ممکن است دایرکتوریهای واسطهای بین دایرکتوری مربوط به ماژول و دایرکتوری ریشهٔ سلسلهمراتب بسته برای کد منبع ماژول وجود داشته باشد.
برای نمونه، در یک سلسلهمراتب منبع ماژول، فایل منبع نوعی به نام com.example.MyClass در ماژولی به نام my.library ممکن است در فایلی مانند my.library/src/main/java/com/example/MyClass.java ذخیره شود..SH "گزینه مسیر منبع ماژول (THE MODULE SOURCE PATH OPTION)"
گزینهٔ --module-source-path دارای دو شکل است: یک شکل مختص ماژول (module-specific) که در آن برای هر ماژولِ حاوی کدی که باید کامپایل شود، یک مسیر بسته مشخص میگردد، و یک شکل الگوی ماژول (module-pattern) که در آن مسیر منبع برای هر ماژول توسط یک الگو تعیین میشود. شکل مختص ماژول معمولاً زمانی که تنها تعداد کمی ماژول در کار باشند سادهتر است؛ شکل الگوی ماژول ممکن است زمانی که تعداد ماژولها زیاد باشد و ماژولها به شیوهای منظم و قابل توصیف با یک الگو سازماندهی شده باشند، راحتتر باشد.
میتوان چندین نمونه از گزینهٔ --module-source-path را مشخص کرد که هر یک از شکل الگوی ماژول یا شکل مختص ماژول استفاده میکند، مشروط بر محدودیتهای زیر:
- •
- شکل الگوی ماژول حداکثر یک بار میتواند استفاده شود
- •
- شکل مختص ماژول برای هر ماژول دادهشده حداکثر یک بار میتواند استفاده شود
اگر از شکل مختص ماژول برای هر ماژولی استفاده شود، مسیر جستجوی مرتبط با آن بر هر مسیری که در غیر این صورت ممکن بود از شکل الگوی ماژول استنباط شود، اولویت خواهد داشت.
شکل مختص ماژول (Module-specific form)
شکل مختص ماژول امکان تعیین یک مسیر جستجوی صریح را برای هر ماژول خاص فراهم میکند. این شکل به صورت زیر است:
- •
- --module-source-path module-name=file-path (path-separator file-path)*
نویسهٔ جداکننده مسیر در ویندوز ; و در غیر این صورت : است.
نکته: این ساختار شبیه شکلی است که برای گزینهٔ --patch-module استفاده میشود.
شکل الگوی ماژول (Module-pattern form)
شکل الگوی ماژول امکان تعریف موجز مسیر منبع ماژول را برای هر تعداد ماژول که به شیوهای منظم سازمانیافتهاند فراهم میکند.
- •
- --module-source-path pattern
الگو بر اساس قواعد زیر که به ترتیب اعمال میشوند، تعریف میگردد:
- •
- آرگومان به عنوان مجموعهای از بخشها در نظر گرفته میشود که با نویسهٔ جداکنندهٔ مسیر (; در ویندوز، و در غیر این صورت :) از هم جدا شدهاند.
- •
- هر بخش حاوی آکولادهایی به شکل
-
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 )*
نویسهٔ جداکننده مسیر در ویندوز ; و در غیر این صورت : است. مسیرهای دادهشده برای ماژول باید ریشه سلسلهمراتب بسته را برای محتویات آن ماژول مشخص کنند.
این گزینه برای هر ماژول مشخص حداکثر میتواند یک بار داده شود. هر محتوایی در این مسیر، محتوای همنام بعدی در مسیر و در ماژول وصلهشده را پنهان خواهد کرد.
هنگام وصلهکردن کد مبدا به بیش از یک ماژول، گزینهٔ --module-source-path نیز باید به کار رود تا دایرکتوری خروجی در یک سلسلهمراتب ماژول سازماندهی شده و توانایی نگهداری پروندههای کلاس کامپایلشده را برای ماژولهای در حال کامپایل داشته باشد.
پردازش حاشیهنویسی (ANNOTATION PROCESSING)
دستور javac پشتیبانی مستقیمی را از پردازش حاشیهنویسیها (annotation processing) فراهم میکند.
رابط برنامهنویسی (API) مربوط به پردازندههای حاشیهنویسی در بستهها و زیربستههای javax.annotation.processing و javax.lang.model تعریف شده است..SS سازوکار پردازش حاشیهنویسیها (How Annotation Processing Works)
مگر آنکه پردازش حاشیهنویسی با گزینهٔ -proc:none غیرفعال شده باشد، کامپایلر برای یافتن پردازشگرهای حاشیهنویسی در دسترس جستجو میکند. مسیر جستجو را میتوان با گزینهٔ -processorpath مشخص کرد. اگر مسیری مشخص نشود، از مسیر کلاس کاربر (user class path) استفاده میشود. پردازشگرها با استفاده از فایلهای پیکربندی ارائهدهندهٔ خدمات به نام META-INF/services/javax.annotation.processing.Processor در مسیر جستجو یافته میشوند. چنین فایلهایی باید حاوی نامهای پردازشگرهای حاشیهنویسیِ مورد استفاده باشند که در هر سطر یک نام درج شده است. همچنین میتوان پردازشگرها را صراحتاً با استفاده از گزینهٔ -processor مشخص کرد.
پس از بررسی فایلهای منبع و کلاسها در خط فرمان برای تعیین حاشیهنویسیهای موجود، کامپایلر پردازشگرها را وارسی میکند تا مشخص کند چه حاشیهنویسیهایی را پردازش میکنند. هنگامی که یک تطابق پیدا شود، آن پردازشگر فراخوانی میشود. یک پردازشگر میتواند مدعی مالکیت (claim) حاشیهنویسیهایی شود که پردازش میکند؛ در این صورت تلاش دیگری برای یافتن پردازشگر برای آن حاشیهنویسیها انجام نمیشود. پس از آنکه ادعای مالکیت تمام حاشیهنویسیها انجام شد، کامپایلر به دنبال پردازشگرهای بیشتری نمیگردد.
اگر پردازشگری فایلهای منبع جدیدی تولید کند، دور دیگری از پردازش حاشیهنویسی رخ میدهد: تمامی فایلهای منبع تازه تولیدشده بررسی شده و حاشیهنویسیها همانند قبل پردازش میشوند. هر پردازشگری که در دورهای پیشین فراخوانی شده باشد، در تمامی دورهای بعدی نیز فراخوانی میشود. این روند تا زمانی که هیچ فایل منبع جدیدی تولید نشود ادامه مییابد.
پس از پایان دوری که در آن هیچ فایل منبع جدیدی تولید نشده باشد، پردازشگرهای حاشیهنویسی برای آخرین بار فراخوانی میشوند تا فرصتی برای تکمیل کارهای باقیمانده داشته باشند. در نهایت، مگر در صورتی که از گزینهٔ -proc:only استفاده شده باشد، کامپایلر فایلهای منبع اصلی و تمامی فایلهای تولیدشده را کامپایل میکند.
اگر از یک پردازشگر حاشیهنویسی استفاده میکنید که فایلهای منبع اضافی را برای گنجانده شدن در کامپایل تولید میکند، میتوانید یک ماژول پیشفرض را برای فایلهای تازه تولیدشده تعیین کنید تا در مواردی که اعلان ماژول تولید نشده است استفاده شود. در این حالت، از گزینهٔ --default-module-for-created-files استفاده کنید.
محیط کامپایل و محیط زمان اجرا (Compilation Environment and Runtime Environment)
اعلانهای موجود در فایلهای منبع و فایلهای کلاس کامپایلشدهٔ قبلی توسط javac در یک محیط کامپایل تحلیل میشوند که از محیط زمان اجرا مورد استفاده برای اجرای خودِ javac متمایز است. اگرچه شباهت عمدی میان بسیاری از گزینههای javac و گزینههای همنام برای launcher جاوا وجود دارد، مانند --class-path، --module-path و غیره، اما درک این نکته اهمیت دارد که به طور کلی گزینههای javac تنها بر محیطی که فایلهای منبع در آن کامپایل میشوند تأثیر میگذارند و بر عملکرد خود javac اثری ندارند.
تمایز میان محیط کامپایل و محیط زمان اجرا هنگام استفاده از پردازشگرهای حاشیهنویسی اهمیت زیادی دارد. اگرچه پردازشگرهای حاشیهنویسی عناصری (اعلانهایی) را پردازش میکنند که در محیط کامپایل وجود دارند، اما خودِ پردازشگر حاشیهنویسی در محیط زمان اجرا اجرا میشود. اگر یک پردازشگر حاشیهنویسی به کتابخانههایی وابسته باشد که درون ماژولها نیستند، این کتابخانهها را میتوان به همراه خود پردازشگر در مسیر پردازشگر قرار داد. (گزینهٔ --processor-path را ببینید.) اگر پردازشگر حاشیهنویسی و وابستگیهای آن در ماژولها باشند، باید در عوض از مسیر ماژول پردازشگر استفاده کنید. (گزینهٔ --processor-module-path را ببینید.) در صورتی که این موارد ناکافی باشند، ممکن است پیکربندی بیشتری برای محیط زمان اجرا لازم باشد. این کار را میتوان به دو روش انجام داد:
- 1.
- اگر javac از خط فرمان فراخوانی شود، میتوان با افزودن پیشوند -J به گزینه، آن را به زمان اجرای زیرین منتقل کرد.
- 2.
- میتوانید یک نمونه از Java Virtual Machine را مستقیماً راهاندازی کرده و از گزینههای خط فرمان و API برای پیکربندی محیطی استفاده کنید که در آن javac از طریق یکی از APIهای خود فراخوانی شود.
کامپایل برای نگارشهای پیشین پلتفرم (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های مستند و پشتیبانیشده برای آن نگارش قابل استفاده هستند؛ شما نمیتوانید از هیچ گزینهای برای شکستن کپسولهسازی به منظور دسترسی به کلاسهای داخلی استفاده کنید..SH "رابطهای برنامهنویسی (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) یافت میشوند، کاملاً داخلی بوده و در هر زمانی ممکن است تغییر کنند.
مثالهای استفاده از کلیدهای -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
- درباره مواردی هشدار میدهد که با کامنت Javadoc با عنوان @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 بررسی کرده و برای هر موردی که یافت شود، یک پیام هشدار ارائه میدهد. حالتهای fall-through مواردی در یک بلوک switch، به جز آخرین case در بلوک هستند که کد آنها شامل دستور break نیست، و باعث میشود اجرای کد از آن مورد به case بعدی سرازیر شود (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 استفاده شده باشد، کامپایلر هشداری درباره امکان fall-through به 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
- درباره مسائل مربوط به رونویسی (override) متدها هشدار میدهد. برای مثال، دو کلاس زیر را در نظر بگیرید:
-
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 درباره عناصر نامعتبر مسیر و دایرکتوریهای ناموجود مسیر در خط فرمان (با توجه به مسیر کلاسها، مسیر مبدأ، و سایر مسیرها) هشدار میدهد. چنین هشدارهایی را نمیتوان با یادداشت @SuppressWarnings نادیده گرفت. برای مثال:
- •
- Linux و macOS: javac -Xlint:path -classpath /nonexistentpath Example.java
- •
- Windows: 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 بهشدت به جزئیات کلاس وابسته است و ممکن است بسته به پیادهسازیهای کامپایلر متفاوت باشد. در نتیجه، این امر ممکن است منجر به بروز استثناهای غیرمنتظره InvalidClassExceptions در طول فرایند سریالزدایی (deserialization) شود. برای تضمین یک مقدار serialVersionUID یکدست در میان پیادهسازیهای مختلف کامپایلر جاوا، کلاس سریالپذیر باید صریحاً مقدار 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 حذف کنید.
- 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 پشتیبانی نمیکنند حفظ شود. به دلیل پاکسازی نوع (type erasure)، هر دو نوع 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); } } }
یک نوع تحققناپذیر (non-reifiable) نوعی است که اطلاعات نوع آن در زمان اجرا بهطور کامل در دسترس نیست.
کامپایلر برای تعریف متد ArrayBuilder.addToList هشدار زیر را صادر میکند:
-
warning: [varargs] Possible heap pollution from parameterized vararg type T
هنگامی که کامپایلر با یک متد varargs مواجه میشود، پارامتر صوری varargs را به یک آرایه تبدیل میکند. با این حال، زبان برنامهنویسی جاوا ایجاد آرایههایی از انواع پارامتریشده را مجاز نمیداند. در متد ArrayBuilder.addToList، کامپایلر پارامتر صوری varargs با عنوان T... elements را به پارامتر صوری T[] elements که یک آرایه است، تبدیل میکند. با این وجود، به دلیل پاکسازی نوع (type erasure)، کامپایلر پارامتر صوری varargs را به Object[] elements تبدیل میکند. در نتیجه، احتمال وقوع آلودگی هیپ (heap pollution) وجود دارد.
| 2021 | JDK 17 |