| JAVAC(1) | JDK Commands | JAVAC(1) |
نام (NAME)
javac - کامپایلر رسمی زبان جاوا (نسخه ۲۶)
خلاصه دستور (SYNOPSIS)
javac [گزینهها] [فایلهایمنبع-یا-نامهایکلاس]
- گزینهها
- گزینههای خط فرمان.
- فایلهایمنبع-یا-نامهایکلاس
- فایلهای منبعی که باید کامپایل شوند (برای مثال، Shape.java) یا نام کلاسهای از پیش کامپایلشده برای پردازش حاشیهنویسیها (برای مثال، geometry.MyShape).
توضیحات (DESCRIPTION)
دستور javac فایلهای منبع حاوی تعاریف ماژول، بسته و نوع نوشتهشده به زبان برنامهنویسی جاوا را میخواند و آنها را به فایلهای کلاس که روی ماشین مجازی جاوا (JVM) اجرا میشوند، کامپایل میکند.
دستور javac همچنین میتواند حاشیهنویسیها (annotations) را در فایلهای منبع و کلاسهای جاوا پردازش کند.
فایلهای منبع باید پسوند نام فایل .java داشته باشند. فایلهای کلاس دارای پسوند نام فایل .class هستند. هر دو فایل منبع و کلاس معمولاً دارای نامهایی هستند که محتوای آنها را مشخص میکند. برای مثال، کلاسی به نام Shape در یک فایل منبع به نام Shape.java تعریف شده و به یک فایل کلاس به نام Shape.class کامپایل میشود.
دو روش برای تعیین فایلهای منبع برای javac وجود دارد:
- برای تعداد کمی از فایلهای منبع، میتوانید نام فایلهای آنها را مستقیماً در خط فرمان فهرست کنید.
- برای تعداد زیادی از فایلهای منبع، میتوانید از گزینه @filename در خط فرمان برای تعیین یک فایل آرگومان که نام فایلها در آن فهرست شده است، استفاده کنید. برای توضیحات این گزینه به گزینههای استاندارد و برای توضیحات فایلهای آرگومان javac به بخش فایلهای آرگومان خط فرمان مراجعه کنید.
ترتیب فایلهای منبع تعیینشده در خط فرمان یا در فایل آرگومان اهمیتی ندارد. دستور javac فایلها را با هم و به صورت یک گروه کامپایل میکند و به طور خودکار هرگونه وابستگی بین تعاریف موجود در فایلهای منبع مختلف را حلوفصل مینماید.
دستور javac انتظار دارد که فایلهای منبع در یک یا چند ساختار سلسلهمراتبی دایرکتوری روی سیستم فایل مرتب شده باشند، همانطور که در بخش آرایش و ساختار کد منبع شرح داده شده است.
برای کامپایل یک فایل منبع، javac باید اعلان هر کلاس یا رابطی (interface) را که توسط کدهای درون فایل منبع استفاده، گسترش (extend) یا پیادهسازی (implement) شده است، پیدا کند. این کار به javac امکان میدهد بررسی کند که آیا کد دسترسی لازم به آن کلاسها و رابطها را دارد یا خیر. به جای تعیین صریح فایلهای منبع آن کلاسها و رابطها، میتوانید از گزینههای خط فرمان استفاده کنید تا به javac بگویید کجا به دنبال فایلهای منبع آنها بگردد. اگر آن فایلهای منبع را قبلاً کامپایل کردهاید، میتوانید با استفاده از گزینهها به javac بگویید کجا به دنبال فایلهای کلاس مربوطه بگردد. این گزینهها که همگی نامهایی با پسوند "path" دارند، در بخش گزینههای استاندارد و همچنین در بخشهای پیکربندی کامپایل و جستجوی تعاریف ماژول، بسته و نوع شرح داده شدهاند.
به طور پیشفرض، javac هر فایل منبع را به یک فایل کلاس در همان دایرکتوری فایل منبع کامپایل میکند. با این حال، توصیه میشود با استفاده از گزینه -d یک دایرکتوری مقصد جداگانه تعیین کنید.
گزینههای خط فرمان و متغیرهای محیطی نیز نحوه انجام وظایف مختلف توسط javac را کنترل میکنند:
- کامپایل کد برای اجرا روی نگارشهای قدیمیتر JDK.
- کامپایل کد برای اجرا تحت دیباگر.
- بررسی مسائل نگارشی و سبکی در کد منبع جاوا.
- بررسی مشکلات موجود در کامنتهای javadoc (/** ... */).
- پردازش حاشیهنویسیها در فایلهای منبع و فایلهای کلاس.
- ارتقا و وصلهزدن ماژولها در محیط زمان کامپایل.
دستور javac از کامپایل برای نگارشهای قبلی پلتفرم پشتیبانی میکند و همچنین میتواند از داخل کد جاوا با استفاده از چندین رابط برنامهنویسی (API) فراخوانی شود.
گزینهها (OPTIONS)
دستور javac شامل گزینههای استاندارد و گزینههای اضافی است که یا غیراستاندارد هستند یا برای استفادههای پیشرفته در نظر گرفته شدهاند.
برخی از گزینهها یک یا چند آرگومان میپذیرند. اگر آرگومانی حاوی فاصله یا نویسههای فاصلهساز دیگر باشد، مقدار آن باید بر اساس قواعد محیط مورد استفاده برای فراخوانی javac درون علامت نقلقول قرار گیرد. اگر گزینه با یک خط تیره تکی (-) شروع شود، بسته به گزینه، آرگومان باید بلافاصله پس از نام گزینه بیاید، یا با دونقطه (:) یا فاصله جدا شود. اگر گزینه با دو خط تیره (--) شروع شود، آرگومان میتواند با فاصله یا با نویسه مساوی (=) بدون هیچ فاصله اضافی جدا شود. برای مثال:
-
-Aname="J. Duke" -proc:only -d myDirectory --module-version 3 --module-version=3
در فهرستهای گزینههای زیر، آرگومان path نشاندهنده یک مسیر جستجو است که از فهرستی از مکانهای سیستم فایل تشکیل شده و با نویسه جداکننده مسیر پلتفرم جدا میشوند (نقطهویرگول ; در ویندوز، یا دونقطه : در سایر سیستمها). بسته به گزینه، مکانهای سیستم فایل میتوانند دایرکتوریها، فایلهای JAR یا فایلهای JMOD باشند.
گزینههای استاندارد (Standard Options)
- @filename
- گزینهها و نام فایلها را از یک فایل میخواند. برای کوتاهتر یا سادهتر کردن دستور javac، میتوانید یک یا چند فایل حاوی آرگومانهای دستور javac (به جز گزینههای -J) را مشخص کنید. این کار به شما امکان میدهد در هر سیستمعاملی دستورات javac با هر طولی بسازید. بخش فایلهای آرگومان خط فرمان را ببینید.
- -Akey[=value]
- گزینههایی را برای ارسال به پردازشگرهای حاشیهنویسی مشخص میکند. این گزینهها مستقیماً توسط javac تفسیر نمیشوند، بلکه برای استفاده در اختیار تکتک پردازشگرها قرار میگیرند. مقدار key باید یک یا چند شناسه باشد که با نقطه (.) جدا شدهاند.
- --add-modules module,module
- ماژولهای ریشه را برای حلوفصل علاوه بر ماژولهای اولیه، یا در صورت قرار دادن ALL-MODULE-PATH برای module، تمام ماژولهای موجود در مسیر ماژول را مشخص میکند.
- --boot-class-path path یا -bootclasspath path
- محل فایلهای کلاس bootstrap را رونویسی (override) میکند.
- --class-path path، -classpath path یا -cp path
- محل جستجو برای فایلهای کلاس کاربر و پردازشگرهای حاشیهنویسی را مشخص میکند. این مسیر کلاس جایگزین مسیر کلاس کاربر در متغیر محیطی CLASSPATH میشود.
- اگر گزینههای --class-path، -classpath یا -cp تعیین نشده باشند، مسیر کلاس کاربر مقدار متغیر محیطی CLASSPATH (در صورت تنظیم بودن) یا دایرکتوری جاری خواهد بود.
- اگر کد برای ماژولها کامپایل نمیشود و گزینه --source-path یا -sourcepath تعیین نشده باشد، مسیر کلاس کاربر برای فایلهای منبع نیز جستجو میشود.
- اگر گزینه -processorpath تعیین نشده باشد، مسیر کلاس برای پردازشگرهای حاشیهنویسی نیز جستجو میشود.
- -d directory
- دایرکتوری مقصد (یا دایرکتوری خروجی کلاس) را برای فایلهای کلاس تعیین میکند. اگر کلاسی بخشی از یک بسته باشد، javac فایل کلاس را در یک زیردایرکتوری متناسب با نام ماژول (در صورت وجود) و نام بسته قرار میدهد. این دایرکتوری و زیردایرکتوریهای لازم در صورت عدم وجود به طور خودکار ساخته خواهند شد.
- -deprecation
- توضیحاتی در مورد هر مورد استفاده یا بازنویسی (override) یک عضو یا کلاس منسوخشده (deprecated) نمایش میدهد. بدون گزینه -deprecation، دستور javac خلاصهای از فایلهای منبعی را که از اعضا یا کلاسهای منسوخشده استفاده یا آنها را بازنویسی کردهاند، نمایش میدهد. گزینه -deprecation معادل کوتاهشده -Xlint:deprecation است.
- --enable-preview
- قابلیتهای پیشنمایش زبان را فعال میکند. همچنین دسته lint مربوط به preview را غیرفعال میکند. همراه با -source یا --release استفاده میشود.
- -encoding encoding
- رمزگذاری نویسه مورد استفاده توسط فایلهای منبع را مشخص میکند، مانند EUC-JP و UTF-8. اگر گزینه -encoding مشخص نشده باشد، از مبدل پیشفرض پلتفرم استفاده میشود.
- -endorseddirs directories
- محل مسیر استانداردهای تاییدشده (endorsed standards) را رونویسی میکند.
- -extdirs directories
- محل افزونههای نصبشده را رونویسی میکند. directories فهرستی از دایرکتوریها است که با جداکننده مسیر پلتفرم (; در ویندوز و : در سایر سیستمها) جدا شدهاند. هر فایل JAR در دایرکتوریهای مشخصشده برای یافتن فایلهای کلاس جستجو میشود. تمام فایلهای JAR پیدا شده بخشی از مسیر کلاس میشوند.
- -g
- تمامی اطلاعات خطایابی (دیباگ) از جمله متغیرهای محلی را تولید میکند. به طور پیشفرض، فقط اطلاعات مربوط به شماره خطوط و فایلهای منبع تولید میشود.
- -g:[lines, vars, source]
- فقط انواع اطلاعات دیباگ تعیینشده در فهرست کلیدواژههای جداشده با کاما را تولید میکند. کلیدواژههای معتبر عبارتند از:
- -g:none
- هیچگونه اطلاعات دیباگی تولید نمیکند.
- -h directory
- محل قرارگیری فایلهای هدر محلی (native header files) تولیدشده را مشخص میکند.
- --help، -help یا -?
- خلاصهای از گزینههای استاندارد را چاپ میکند.
- --help-extra یا -X
- خلاصهای از مجموعه گزینههای اضافی را چاپ میکند.
- --help-lint
- کلیدهای پشتیبانیشده برای گزینه -Xlint را چاپ میکند.
- -implicit:[none, class]
- تعیین میکند که آیا برای فایلهای ارجاعشده به صورت ضمنی (implicit) فایل کلاس تولید شود یا خیر:
- -implicit:class --- فایلهای کلاس را به طور خودکار تولید میکند.
- -implicit:none --- از تولید فایل کلاس جلوگیری میکند. اگر این گزینه مشخص نشود، مقدار پیشفرض تولید خودکار فایلهای کلاس است. در این حالت، اگر در حین پردازش حاشیهنویسی، فایل کلاسی تولید شود، کامپایلر یک هشدار صادر میکند. وقتی گزینه -implicit به صراحت تنظیم شود، این هشدار صادر نمیشود. به بخش جستجوی تعاریف ماژول، بسته و نوع مراجعه کنید.
- -Joption
- گزینه option را به سیستم زمان اجرا ارسال میکند، که در آن option یکی از گزینههای جاوا است که در دستور java شرح داده شده است. برای مثال، -J-Xms48m حافظه راهاندازی را روی ۴۸ مگابایت تنظیم میکند.
- --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
- محل یافتن فایلهای منبع را هنگام کامپایل کد در چندین ماژول مشخص میکند. به بخش گزینه مسیر منبع ماژول مراجعه کنید.
- --module-version version
- نسخه ماژولهای در حال کامپایل را مشخص میکند.
- -nowarn
- فقط هشدارهای اجباری را تولید میکند.
- -parameters
- متاداده را برای بازتاب (reflection) روی پارامترهای متد تولید میکند. نامهای پارامترهای صوری سازندهها و متدها را در فایل کلاس تولیدشده ذخیره میکند تا متد java.lang.reflect.Executable.getParameters از API بازتاب بتواند آنها را بازیابی کند.
- -proc:[none, only, full]
- کنترل میکند که آیا پردازش حاشیهنویسی و کامپایل انجام شوند یا خیر.
- -proc:none به این معنی است که کامپایل بدون پردازش حاشیهنویسی انجام میشود.
- -proc:only به این معنی است که فقط پردازش حاشیهنویسی بدون هیچگونه کامپایل بعدی انجام میشود.
- -proc:full به این معنی است که هم پردازش حاشیهنویسی و هم کامپایل انجام میشوند. اگر از این گزینه استفاده نشود، در صورتی که حداقل یک گزینه دیگر برای پیکربندی صریح پردازش حاشیهنویسی استفاده شده باشد، پردازش حاشیهنویسی و کامپایل انجام خواهند شد.
- -processor class1[,class2,class3...]
- نام پردازشگرهای حاشیهنویسی که باید اجرا شوند. این گزینه فرآیند کشف خودکار و پیشفرض را نادیده میگیرد.
- --processor-module-path path
- مسیر ماژول مورد استفاده برای یافتن پردازشگرهای حاشیهنویسی را مشخص میکند.
- --processor-path path یا -processorpath path
- محل یافتن پردازشگرهای حاشیهنویسی را مشخص میکند. اگر از این گزینه استفاده نشود، مسیر کلاس برای یافتن پردازشگرها جستجو میشود.
- -profile profile
- بررسی میکند که API مورد استفاده در پروفایل مشخصشده در دسترس باشد. این گزینه منسوخ شده و ممکن است در نگارشهای آینده حذف شود.
- --release release
- کد منبع را بر اساس قواعد زبان برنامهنویسی جاوا برای نگارش مشخصشده Java SE کامپایل میکند و فایلهای کلاسی تولید مینماید که آن نگارش را هدف قرار میدهند. کد منبع در برابر API ترکیبی Java SE و JDK برای نگارش مشخصشده کامپایل میشود.
- -s directory
- دایرکتوری مورد استفاده برای قرار دادن فایلهای منبع تولیدشده را مشخص میکند. اگر کلاسی بخشی از یک بسته باشد، کامپایلر فایل منبع را در یک زیردایرکتوری متناسب با نام ماژول (در صورت وجود) و نام بسته قرار میدهد. این دایرکتوری و زیردایرکتوریهای لازم در صورت عدم وجود به طور خودکار ایجاد میشوند.
- --source release یا -source release
- کد منبع را بر اساس قواعد زبان برنامهنویسی جاوا برای نگارش مشخصشده Java SE کامپایل میکند. مقادیر پشتیبانیشده برای release عبارتند از نگارش فعلی Java SE و تعداد محدودی از نگارشهای پیشین که در راهنمای خط فرمان ذکر شدهاند.
- --source-path path یا -sourcepath path
- محل یافتن فایلهای منبع را مشخص میکند. به جز هنگام کامپایل همزمان چندین ماژول، این همان مسیر کد منبع است که برای جستجوی تعاریف کلاس یا رابط استفاده میشود.
- --system jdk | none
- محل ماژولهای سیستمی را رونویسی میکند.
- --target release یا -target release
- فایلهای class مناسب برای نگارش مشخصشده Java SE را تولید میکند. مقادیر پشتیبانیشده برای release عبارتند از نگارش فعلی Java SE و تعداد محدودی از نگارشهای قبلی که در راهنمای خط فرمان آمده است.
- --upgrade-module-path path
- محل ماژولهای قابل ارتقا را رونویسی میکند.
- -verbose
- پیامهایی درباره اقدامات در حال انجام توسط کامپایلر چاپ میکند. این پیامها شامل اطلاعاتی درباره هر کلاس بارگذاریشده و هر فایل منبع کامپایلشده است.
- --version یا -version
- اطلاعات نگارش را چاپ میکند.
- -Werror
- در صورت بروز هرگونه هشدار، فرآیند کامپایل را متوقف میکند؛ این شامل هشدارهای تمام دستههای lint و همچنین هشدارهای غیر lint میشود.
- -Werror:[-]key(,[-]key)*
- دستههای lint را مشخص میکند که هشدارهای آنها باید موجب خاتمه کامپایل شوند. کلیدهای all و none به ترتیب تمام دستهها را شامل یا حذف میکنند؛ سایر کلیدها دسته مربوطه را شامل میشوند، یا اگر قبل از آنها یک خط تیره (-) بیاید، آن را مستثنی میکنند. به طور پیشفرض، هیچ دستهای لحاظ نشده است. برای خاتمه کامپایل، دسته مورد نظر باید فعال نیز باشد (در صورت لزوم، از طریق -Xlint). برای فهرست کلیدهای دستهبندی lint، بخش -Xlint را در ادامه ببینید.
گزینههای اضافی (Extra Options)
- --add-exports module/package=other-module(,other-module)*
- بستهای را مشخص میکند که باید از ماژول تعریفکننده آن به ماژولهای اضافی، یا در صورت قرار دادن مقدار ALL-UNNAMED برای other-module به تمام ماژولهای بینام، صادرشده تلقی شود.
- --add-reads module=other-module(,other-module)*
- ماژولهای اضافی را مشخص میکند که باید توسط یک ماژول دادهشده موردنیاز تلقی شوند.
- --default-module-for-created-files module-name
- ماژول هدف پشتیبان (fallback) را برای فایلهای ایجادشده توسط پردازشگرهای حاشیهنویسی در صورت عدم تعیین یا استنتاج مشخص میکند.
- --disable-line-doc-comments
- پشتیبانی از کامنتهای مستندسازی با خطوطی که با /// شروع میشوند را غیرفعال میکند.
- -Djava.endorsed.dirs=dirs
- محل مسیر استانداردهای تاییدشده را رونویسی میکند.
- -Djava.ext.dirs=dirs
- محل افزونههای نصبشده را رونویسی میکند.
- --patch-module module=path
- یک ماژول را با کلاسها و منابع موجود در فایلهای JAR یا دایرکتوریها رونویسی یا تقویت میکند.
- -Xbootclasspath:path
- محل فایلهای کلاس bootstrap را رونویسی میکند.
- -Xbootclasspath/a:path
- یک پسوند به مسیر کلاس bootstrap اضافه میکند.
- -Xbootclasspath/p:path
- یک پیشوند به مسیر کلاس bootstrap اضافه میکند.
- -Xdiags:[compact, verbose]
- حالت عیبیابی (تشخیصی) را انتخاب میکند.
- -Xdoclint
- بررسیهای توصیهشده برای خطاهای کامنتهای مستندسازی را فعال میکند.
- -Xdoclint:(all|none|[-]group)[/access]
- گروههای خاصی از بررسیها را در کامنتهای مستندسازی فعال یا غیرفعال میکند.
-Xdoclint:all/protected
-Xdoclint:all,-html/package
- -Xdoclint/package:[-]packages(,[-]package)*
- بررسیها را در بستههای مشخصشده فعال یا غیرفعال میکند. هر package یا نام کامل یک بسته است یا یک پیشوند نام بسته به همراه .* که به تمام زیربستههای بسته دادهشده گسترش مییابد. هر package میتواند با یک خط تیره (-) شروع شود تا بررسیها برای یک یا چند بسته خاص غیرفعال شوند.
- -Xlint
- تمامی هشدارهای توصیهشده را فعال میکند. در این نگارش، فعال کردن تمامی هشدارهای موجود توصیه میشود.
- -Xlint:[-]key(,[-]key)*
- دستههای هشدار را با استفاده از یک یا چند کلید شرح داده شده در زیر که با کاما جدا شدهاند، فعال و/یا غیرفعال میکند. کلیدهای all و none به ترتیب تمام دستهها را فعال یا غیرفعال میکنند؛ سایر کلیدها دسته متناظر را فعال کرده، یا اگر قبل از آنها خط تیره (-) باشد، آن را غیرفعال مینمایند.
- all: تمامی دستههای هشدار را فعال میکند.
- auxiliaryclass: درباره کلاس کمکی که در یک فایل منبع پنهان شده و از فایلهای دیگر استفاده میشود، هشدار میدهد.
- cast: درباره استفاده از تبدیل نوعهای (cast) غیرضروری هشدار میدهد.
- classfile: درباره مسائل مربوط به محتویات فایل کلاس هشدار میدهد.
- dangling-doc-comments: درباره کامنتهای مستندسازی اضافی یا جابجا شده در نزدیکی ابتدای یک اعلان هشدار میدهد.
- deprecation: درباره استفاده از موارد منسوخشده هشدار میدهد.
- dep-ann: درباره مواردی که در javadoc منسوخ علامتگذاری شدهاند اما فاقد حاشیهنویسی @Deprecated هستند هشدار میدهد.
- divzero: درباره تقسیم بر عدد صحیح ثابت 0 هشدار میدهد.
- empty: درباره دستور خالی بعد از if هشدار میدهد.
- exports: درباره مسائل مربوط به صادرات ماژول هشدار میدهد.
- fallthrough: درباره افتادن (fall-through) از یک حالت دستور switch به حالت بعدی هشدار میدهد.
- finally: درباره بندهای finally که به طور عادی خاتمه نمییابند هشدار میدهد.
- identity: درباره استفاده از یک کلاس مبتنی بر مقدار (value-based) در جایی که یک کلاس هویتی (identity) انتظار میرود، هشدار میدهد.
- incubating: درباره استفاده از ماژولهای آزمایشی/انکوباتور (incubating) هشدار میدهد.
- lossy-conversions: درباره تبدیلهای احتمالی همراه با اتلاف داده در انتسابهای مرکب هشدار میدهد.
- missing-explicit-ctor: درباره عدم وجود سازندههای صریح در کلاسهای عمومی (public) و حفاظتشده (protected) در بستههای صادرشده هشدار میدهد.
- module: درباره مسائل مربوط به سیستم ماژول هشدار میدهد.
- opens: درباره مسائل مربوط به باز کردن ماژول (opens) هشدار میدهد.
- options: درباره مسائل مربوط به استفاده از گزینههای خط فرمان هشدار میدهد.
- output-file-clash: در صورتی که هر فایل خروجی در حین کامپایل بازنویسی شود، هشدار میدهد. این وضعیت ممکن است برای مثال در سیستمهای فایلی حساس به حروف بزرگ و کوچک رخ دهد.
- overloads: درباره مسائل مربوط به سربارگذاری (overload) متدها هشدار میدهد.
- overrides: درباره مسائل مربوط به بازنویسی (override) متدها هشدار میدهد.
- path: درباره عناصر نامعتبر مسیر در خط فرمان هشدار میدهد.
- preview: درباره استفاده از ویژگیهای پیشنمایش زبان هشدار میدهد.
- processing: درباره مسائل مربوط به پردازش حاشیهنویسی هشدار میدهد.
- rawtypes: درباره استفاده از انواع خام (raw types) هشدار میدهد.
- removal: درباره استفاده از API که برای حذف علامتگذاری شده است هشدار میدهد.
- restricted: درباره استفاده از متدهای محدودشده هشدار میدهد.
- requires-automatic: به توسعهدهندگان درباره استفاده از ماژولهای خودکار در بندهای requires هشدار میدهد.
- requires-transitive-automatic: درباره ماژولهای خودکار در requires transitive هشدار میدهد.
- serial: درباره کلاسهای سریالپذیر (serializable) که شناسه نسخه سریالی (serial version ID) ارائه نمیدهند هشدار میدهد. همچنین درباره دسترسی به اعضای غیرعمومی از یک عنصر سریالپذیر هشدار میدهد.
- static: درباره دسترسی به یک عضو ایستا (static) با استفاده از یک نمونه (instance) هشدار میدهد.
- strictfp: درباره استفاده غیرضروری از اصلاحکننده strictfp هشدار میدهد.
- synchronization: درباره تلاش برای همگامسازی روی نمونههای کلاسهای مبتنی بر مقدار هشدار میدهد. این کلید یک نام مستعار منسوخشده برای identity است که همان کاربردها و اثرات را دارد. کاربران تشویق میشوند برای همه کاربردهای آینده و موجود به جای آن از دسته identity استفاده کنند.
- text-blocks: درباره نویسههای فاصلهساز متناقض در تورفتگی بلوکهای متنی هشدار میدهد.
- this-escape: درباره نشت مرجع this در سازندهها پیش از مقداردهی اولیه زیرکلاس هشدار میدهد.
- try: درباره مسائل مربوط به استفاده از بلوکهای try (یعنی try-with-resources) هشدار میدهد.
- unchecked: درباره عملیات بررسینشده (unchecked) هشدار میدهد.
- varargs: درباره متدهای دارای تعداد متغیر آرگومان (varargs) با ایمنی بالقوه نامطمئن هشدار میدهد.
- none: تمامی دستههای هشدار را غیرفعال میکند. به استثنای all و none، کلیدها را میتوان با حاشیهنویسی @SuppressWarnings استفاده کرد تا هشدارها در بخشی از کد منبع در حال کامپایل نادیده گرفته شوند. بخش مثالهای استفاده از کلیدهای -Xlint را ببینید.
- -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 فقط حاوی کامنت باشد، این گزینه فایل package-info.class تولید نمیکند.
- nonempty
- تنها در صورتی فایل package-info.class تولید میکند که package-info.java حاوی حاشیهنویسیهایی با RetentionPolicy.CLASS یا RetentionPolicy.RUNTIME باشد.
- -Xplugin:name args
- نام و آرگومانهای اختیاری پلاگینی را که باید اجرا شود مشخص میکند. در صورت ارائه args، مقدار name و args باید درون نقلقول قرار گیرند یا نویسههای فاصله بین نام و آرگومانها اسکیپ شوند. برای جزئیات بیشتر در مورد API پلاگین، به مستندات API مربوط به jdk.compiler/com.sun.source.util.Plugin مراجعه کنید.
- -Xprefer:[source, newer]
- مشخص میکند که هنگام یافتن همزمان فایل منبع و فایل کلاس برای یک کلاس کامپایلشده ضمنی، کدام فایل با استفاده از یکی از گزینههای زیر خوانده شود. به بخش جستجوی تعاریف ماژول، بسته و نوع مراجعه کنید.
- -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 به همان شیوهای که در خط فرمان تعیین میشود پردازش میگردد.
میتوان از نقلقولهای تکی (') یا دوتایی (") برای محصور کردن آرگومانهای حاوی نویسههای فاصلهساز استفاده کرد. تمام محتوای بین نقلقول باز و اولین نقلقول بسته متناظر با حذف جفت نقلقولها حفظ میشود. در صورتی که نقلقول متناظر پیدا نشود، راهانداز با یک پیام خطا متوقف خواهد شد. فایلهای @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
- فایل آرگومان تکی (Single Argument File)
- میتوانید از یک فایل آرگومان تکی به نام argfile برای نگهداری تمام آرگومانهای javac استفاده کنید:
javac @argfile
- دو فایل آرگومان (Two Argument Files)
- میتوانید دو فایل آرگومان ایجاد کنید: یکی برای گزینههای javac و دیگری برای نام فایلهای منبع. توجه داشته باشید که فهرستهای زیر فاقد نویسههای ادامهدهنده خط هستند.
لینوکس و مکاواس:
-
-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
فایلی به نام sources ایجاد کنید که حاوی موارد زیر باشد: -
MyClass1.java MyClass2.java MyClass3.java
سپس دستور javac را به صورت زیر اجرا کنید:
javac @options @sources
- فایلهای آرگومان دارای مسیر (Argument Files with Paths)
- فایلهای آرگومان میتوانند مسیر داشته باشند، اما نام هر فایلی درون آنها نسبت به دایرکتوری کاری جاری سنجیده میشود (نه نسبت به path1 یا path2):
javac @path1/options @path2/sources
آرایش و ساختار کد منبع (ARRANGEMENT OF SOURCE CODE)
در زبان جاوا، کلاسها و رابطها میتوانند در بستهها سازماندهی شوند و بستهها نیز در ماژولها قرار گیرند. دستور javac انتظار دارد که آرایش فیزیکی فایلهای منبع در دایرکتوریهای سیستم فایل، بازتابی از سازماندهی کلاسها در بستهها و بستهها در ماژولها باشد.
یک قرارداد پذیرفتهشده گسترده این است که نام ماژولها و بستهها با حروف کوچک شروع میشوند و نام کلاسها با حروف بزرگ آغاز میگردند.
آرایش کد منبع برای یک بسته (Arrangement of Source Code for a Package)
هنگامی که کلاسها و رابطها در یک بسته سازماندهی میشوند، بسته به صورت یک دایرکتوری و زیربستههای آن به صورت زیردایرکتوریها نمایش داده میشوند.
برای مثال:
- بسته 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 راحتتر است.
آرایش کد منبع برای یک ماژول (Arrangement of Source Code for a Module)
در زبان جاوا، ماژول مجموعهای از بستهها است که برای استفاده مجدد طراحی شدهاند. علاوه بر فایلهای .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 را برای انجام یک کامپایل پایهای شرح میدهد.
برای جزئیات بیشتر هنگام کامپایل برای نگارشی از پلتفرم که از ماژولها پشتیبانی میکند، به بخش پیکربندی سیستم ماژول مراجعه کنید.
فایلهای منبع (Source Files)
- •
- فایلهای منبعی را که باید کامپایل شوند در خط فرمان مشخص کنید.
اگر خطای کامپایلی وجود نداشته باشد، فایلهای کلاس متناظر در دایرکتوری خروجی قرار میگیرند.
برخی از سیستمها ممکن است حجم ورودی در خط فرمان را محدود کنند؛ برای دور زدن این محدودیتها، میتوانید از فایلهای آرگومان استفاده کنید.
هنگام کامپایل کد برای ماژولها، میتوانید فایلهای منبع را به صورت غیرمستقیم با استفاده از گزینه --module یا -m مشخص نمایید.
دایرکتوری خروجی (Output Directory)
- •
- از گزینه -d برای تعیین دایرکتوری خروجی برای قرار دادن فایلهای کلاس کامپایلشده استفاده کنید.
این خروجی به طور معمول در یک سلسلهمراتب بسته سازماندهی میشود، مگر اینکه کدهای منبع را از چندین ماژول کامپایل کنید، که در این صورت به صورت سلسلهمراتب ماژول سازماندهی خواهد شد.
پس از اتمام کامپایل، اگر یک یا چند ماژول را کامپایل کردهاید، میتوانید دایرکتوری خروجی را در مسیر ماژول برای راهانداز جاوا قرار دهید؛ در غیر این صورت، میتوانید دایرکتوری خروجی را در مسیر کلاس برای راهانداز جاوا قرار دهید.
کد از پیش کامپایلشده (Precompiled Code)
کدی که باید کامپایل شود ممکن است به کتابخانههایی فراتر از آنچه توسط پلتفرم ارائه شده ارجاع دهد. در این صورت، باید این کتابخانهها را در مسیر کلاس یا مسیر ماژول قرار دهید. اگر کد کتابخانه در یک ماژول نیست، آن را در مسیر کلاس قرار دهید؛ اگر در یک ماژول است، آن را در مسیر ماژول قرار دهید.
- از گزینه --class-path برای تعیین کتابخانههایی که باید در مسیر کلاس قرار گیرند استفاده کنید. مکانهای موجود در مسیر کلاس باید در یک سلسلهمراتب بسته سازماندهی شوند. همچنین میتوانید از اشکال جایگزین این گزینه استفاده کنید: -classpath یا -cp.
- از گزینه --module-path برای تعیین کتابخانههایی که باید در مسیر ماژول قرار گیرند استفاده کنید. مکانهای موجود در مسیر ماژول باید ماژولها یا دایرکتوریهای حاوی ماژول باشند. همچنین میتوانید از شکل جایگزین این گزینه استفاده کنید: -p.
برای جزئیات بیشتر در مورد نحوه تغییر پیکربندی پیشفرض ماژولهای کتابخانه، به بخش پیکربندی سیستم ماژول مراجعه کنید.
نکته: گزینههای مسیر کلاس و مسیر ماژول ناسازگار با یکدیگر نیستند، هرچند تعیین مسیر کلاس هنگام کامپایل کد برای یک یا چند ماژول معمول نیست.
فایلهای منبع اضافی (Additional Source Files)
کد مورد نظر برای کامپایل ممکن است به انواعی در فایلهای منبع اضافی ارجاع دهد که در خط فرمان مشخص نشدهاند. در این صورت، باید آن فایلهای منبع را در مسیر منبع یا مسیر ماژول قرار دهید. شما فقط میتوانید یکی از این گزینهها را مشخص کنید: اگر کدی را برای یک ماژول کامپایل نمیکنید یا اگر فقط برای یک ماژول واحد کامپایل میکنید، از مسیر منبع استفاده کنید؛ اگر برای چندین ماژول کامپایل میکنید، از مسیر منبع ماژول استفاده نمایید.
- از گزینه --source-path برای تعیین مکان فایلهای منبع اضافی که ممکن است توسط javac خوانده شوند استفاده کنید. مکانهای موجود در مسیر منبع باید در یک سلسلهمراتب بسته سازماندهی شوند. همچنین میتوانید از شکل جایگزین این گزینه استفاده کنید: -sourcepath.
- از گزینه --module-source-path یک یا چند بار برای تعیین مکان فایلهای منبع اضافی در ماژولهای مختلف که ممکن است توسط javac خوانده شوند، یا هنگام کامپایل فایلهای منبع در چندین ماژول استفاده کنید. میتوانید مکانها را برای هر ماژول به صورت جداگانه مشخص کنید یا فایلهای منبع را طوری سازماندهی کنید که بتوانید مکانها را به صورت یکجا مشخص نمایید. برای جزئیات بیشتر، به بخش گزینه مسیر منبع ماژول مراجعه کنید.
اگر میخواهید بتوانید به انواع موجود در فایلهای منبع اضافی ارجاع دهید اما نمیخواهید آنها کامپایل شوند، از گزینه -implicit استفاده کنید.
نکته: اگر کدی را برای چندین ماژول کامپایل میکنید، باید همیشه یک مسیر منبع ماژول مشخص کنید، و تمام فایلهای منبع مشخصشده در خط فرمان باید در یکی از دایرکتوریهای موجود در مسیر منبع ماژول یا در زیردایرکتوریهای آن قرار داشته باشند.
مثال کامپایل چندین فایل منبع (Example of Compiling Multiple Source Files)
این مثال فایلهای منبع Aloha.java، GutenTag.java، Hello.java و Hi.java را در بسته greetings کامپایل میکند.
لینوکس و مکاواس:
-
% 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
مثال تعیین مسیر کلاس کاربر (Example of Specifying a User Class Path)
پس از تغییر یکی از فایلهای منبع در مثال قبلی، آن را دوباره کامپایل کنید:
لینوکس و مکاواس:
-
pwd /examples javac greetings/Hi.java
ویندوز:
-
C:\>cd \examples C:\>javac greetings\Hi.java
از آنجا که greetings.Hi به کلاسهای دیگر در بسته greetings ارجاع میدهد، کامپایلر باید این کلاسهای دیگر را پیدا کند. مثال قبلی کار میکند زیرا مسیر کلاس کاربر پیشفرض، دایرکتوری حاوی دایرکتوری بسته است. اگر میخواهید این فایل را بدون توجه به دایرکتوری جاری کامپایل مجدد کنید، دایرکتوری examples را با تنظیم CLASSPATH به مسیر کلاس کاربر اضافه کنید. این مثال از گزینه -classpath استفاده میکند.
لینوکس و مکاواس:
javac -classpath /examples /examples/greetings/Hi.java
ویندوز:
C:\>javac -classpath \examples \examples\greetings\Hi.java
اگر greetings.Hi را برای استفاده از یک ابزار بنر تغییر دهید، آن ابزار نیز باید از طریق مسیر کلاس کاربر در دسترس باشد.
لینوکس و مکاواس:
-
javac -classpath /examples:/lib/Banners.jar \ /examples/greetings/Hi.java
ویندوز:
-
C:\>javac -classpath \examples;\lib\Banners.jar ^ \examples\greetings\Hi.java
برای اجرای یک کلاس در بسته greetings، برنامه نیاز به دسترسی به بسته greetings و کلاسهایی دارد که کلاسهای greetings از آنها استفاده میکنند.
لینوکس و مکاواس:
java -classpath /examples:/lib/Banners.jar greetings.Hi
ویندوز:
C:\>java -classpath \examples;\lib\Banners.jar greetings.Hi
پیکربندی سیستم ماژول (CONFIGURING THE MODULE SYSTEM)
اگر میخواهید ماژولهای اضافی را در کامپایل خود بگنجانید، از گزینه --add-modules استفاده کنید. این کار زمانی ضروری است که کدی را کامپایل میکنید که در یک ماژول نیست یا در یک ماژول خودکار است و کد به API موجود در ماژولهای اضافی ارجاع میدهد.
اگر میخواهید مجموعه ماژولهای موجود در کامپایل خود را محدود کنید، از گزینه --limit-modules استفاده کنید. این کار زمانی مفید است که بخواهید اطمینان حاصل کنید کدی که کامپایل میکنید قادر به اجرا روی سیستمی با تعداد محدودی ماژول نصبشده است.
اگر میخواهید کپسولهسازی را بشکنید و مشخص کنید که بستههای اضافی باید از یک ماژول صادرشده تلقی شوند، از گزینه --add-exports استفاده کنید. این کار ممکن است هنگام انجام تست جعبه سفید مفید باشد؛ اتکا به دسترسی به APIهای داخلی در کد محیط عملیاتی به شدت نهی میشود.
اگر میخواهید مشخص کنید که بستههای اضافی باید توسط یک ماژول موردنیاز تلقی شوند، از گزینه --add-reads استفاده کنید. این کار هنگام انجام تست جعبه سفید میتواند مفید باشد؛ اتکا به دسترسی به APIهای داخلی در کد محیط عملیاتی به شدت نهی میشود.
میتوانید با استفاده از گزینه --patch-module محتوای اضافی را به هر ماژولی وصله کنید. برای جزئیات بیشتر به بخش [وصلهزدن ماژولها] مراجعه کنید.
جستجوی تعاریف ماژول، بسته و نوع (SEARCHING FOR MODULE, PACKAGE AND TYPE DECLARATIONS)
برای کامپایل یک فایل منبع، کامپایلر اغلب به اطلاعاتی درباره یک ماژول یا نوع نیاز دارد، اما اعلان آن در فایلهای منبع مشخصشده در خط فرمان موجود نیست.
دستور javac به اطلاعات نوع برای هر کلاس یا رابطی که در فایل منبع استفاده، گسترش داده شده یا پیادهسازی شده است نیاز دارد. این شامل کلاسها و رابطهایی است که صریحاً در فایل منبع ذکر نشدهاند، اما اطلاعاتی را از طریق وراثت ارائه میدهند.
برای مثال، هنگامی که زیرکلاسی از java.awt.Window ایجاد میکنید، از کلاسهای والد Window نیز استفاده میکنید: java.awt.Container، java.awt.Component و java.lang.Object.
هنگام کامپایل کد برای یک ماژول، کامپایلر همچنین باید اعلان آن ماژول را در دسترس داشته باشد.
یک جستجوی موفق ممکن است یک فایل کلاس، یک فایل منبع یا هر دو را پیدا کند. اگر هر دو پیدا شوند، میتوانید از گزینه -Xprefer استفاده کنید تا به کامپایلر دستور دهید از کدام یک استفاده کند.
اگر جستجویی یک فایل منبع را پیدا کرده و استفاده کند، به طور پیشفرض javac آن فایل منبع را کامپایل میکند. این رفتار را میتوان با -implicit تغییر داد.
کامپایلر ممکن است تا پس از اتمام پردازش حاشیهنویسی، متوجه نیاز به برخی اطلاعات نوع نشود. هنگامی که اطلاعات نوع در یک فایل منبع یافت میشود و هیچ گزینه -implicit مشخص نشده باشد، کامپایلر هشداری صادر میکند مبنی بر اینکه فایل بدون قرار گرفتن تحت پردازش حاشیهنویسی در حال کامپایل است. برای غیرفعال کردن هشدار، یا فایل را در خط فرمان مشخص کنید (تا تحت پردازش حاشیهنویسی قرار گیرد) یا از گزینه -implicit برای تعیین اینکه آیا فایلهای کلاس برای چنین فایلهای منبعی تولید شوند یا خیر استفاده نمایید.
روشی که javac تعاریف آن نوعها را پیدا میکند به این بستگی دارد که آیا ارجاع درون کد یک ماژول وجود دارد یا خیر.
جستجوی مسیرهای مبتنی بر بسته (Searching Package Oriented Paths)
هنگام جستجو برای یک فایل منبع یا کلاس در مسیری متشکل از مکانهای مبتنی بر بسته، javac هر مکان در مسیر را به نوبت برای بررسی احتمال وجود فایل بررسی میکند. اولین رخداد یک فایل خاص، هرگونه رخداد بعدی فایلهای همنام را سایهاندازی (پنهان) میکند. این سایهاندازی روی جستجو برای فایلهایی با نام متفاوت تأثیری ندارد. این ویژگی هنگام جستجوی فایلهای منبع که ممکن است در مکانهای مختلفی مانند کد مشترک، کد مختص پلتفرم و کد تولیدشده گروهبندی شده باشند، راحت است. همچنین میتواند هنگام تزریق نسخههای جایگزین یک فایل کلاس به یک بسته، برای مقاصد دیباگ یا سایر دلایل ابزارسازی مفید باشد. اما میتواند خطرناک نیز باشد، مانند زمانی که نسخههای ناسازگار متفاوتی از یک کتابخانه در مسیر کلاس قرار میگیرند.
جستجوی مسیرهای مبتنی بر ماژول (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 در یکی از مکانهای موجود در مسیر منبع یا مسیر منبع ماژول برای آن ماژول خواهد بود.
جستجو برای اعلان یک نوع وقتی ارجاع در ماژول نیست (Searching for the Declaration of a Type When the Reference is not in a Module)
هنگام جستجو برای نوعی که در کدی خارج از ماژول ارجاع داده شده است، javac مکانهای زیر را بررسی میکند:
- کلاسهای پلتفرم (یا انواع موجود در بستههای صادرشده ماژولهای پلتفرم) (این فقط برای فایلهای کلاس کامپایلشده است.)
- انواع موجود در بستههای صادرشده هر ماژولی در مسیر ماژول، در صورت وجود. (این فقط برای فایلهای کلاس کامپایلشده است.)
- انواع موجود در بستههای روی مسیر کلاس و/یا مسیر منبع:
- اگر هر دو مشخص شده باشند، javac به دنبال فایلهای کلاس کامپایلشده در مسیر کلاس و به دنبال فایلهای منبع در مسیر منبع میگردد.
- اگر مسیر کلاس مشخص شده باشد اما مسیر منبع مشخص نشده باشد، javac هم به دنبال فایلهای کلاس کامپایلشده و هم فایلهای منبع در مسیر کلاس میگردد.
- اگر مسیر کلاس مشخص نشده باشد، پیشفرض دایرکتوری جاری است.
هنگام جستجو برای یک نوع در مسیر کلاس و/یا مسیر منبع، اگر هم یک فایل کلاس کامپایلشده و هم یک فایل منبع پیدا شوند، فایلی که اخیراً تغییر یافته به طور پیشفرض استفاده خواهد شد. اگر فایل منبع جدیدتر باشد، کامپایل خواهد شد و ممکن است هر نسخه از پیش کامپایلشده فایل را رونویسی کند. میتوانید از گزینه -Xprefer برای تغییر این رفتار پیشفرض استفاده کنید.
جستجو برای اعلان یک نوع وقتی ارجاع در ماژول است (Searching for the Declaration of a Type When the Reference is in a Module)
هنگام جستجو برای نوعی که در کد درون یک ماژول ارجاع داده شده است، javac اعلان ماژول دربرگیرنده را بررسی میکند تا تعیین کند آیا آن نوع در بستهای است که از ماژول دیگری صادر شده و برای ماژول دربرگیرنده قابل خواندن است یا خیر. اگر چنین باشد، javac مستقیماً به سراغ تعریف آن ماژول میرود تا تعریف نوع مورد نیاز را پیدا کند. مگر اینکه آن ماژول، یکی دیگر از ماژولهای در حال کامپایل باشد، javac فقط به دنبال فایلهای کلاس کامپایلشده خواهد گشت. به عبارت دیگر، javac به دنبال فایلهای منبع در ماژولهای پلتفرم یا ماژولهای موجود در مسیر ماژول نخواهد گشت.
اگر نوع مورد ارجاع در ماژول خواندنی دیگری نباشد، javac ماژول در حال کامپایل را بررسی میکند تا اعلان آن نوع را بیابد. دستور javac به دنبال اعلان نوع به صورت زیر خواهد گشت:
- فایلهای منبع تعیینشده در خط فرمان یا در مسیر منبع یا مسیر منبع ماژول.
- فایلهای از پیش کامپایلشده در دایرکتوری خروجی.
سلسلهمراتبهای دایرکتوری (DIRECTORY HIERARCHIES)
دستور javac عموماً فرض میکند که فایلهای منبع و فایلهای کلاس کامپایلشده در یک ساختار سلسلهمراتبی دایرکتوری سیستم فایل یا در نوعی فایل که ساختار دایرکتوری داخلی دارد (مانند فایل JAR) سازماندهی میشوند. سه نوع ساختار سلسلهمراتبی پشتیبانی میشود: سلسلهمراتب بسته، سلسلهمراتب ماژول و سلسلهمراتب منبع ماژول.
در حالی که javac در مورد سازماندهی کد منبع نسبتاً انعطافپذیر است، فراتر از این انتظار که منبع در یک یا چند سلسلهمراتب بسته سازماندهی شود، و عموماً میتواند ساختارهای تجویزشده توسط محیطهای توسعه و ابزارهای ساخت را در خود جای دهد، ابزارهای جاوا به طور کلی، و به ویژه javac و راهانداز جاوا، در مورد سازماندهی فایلهای کلاس کامپایلشده سختگیرتر هستند و بسته به شرایط در سلسلهمراتبهای بسته یا سلسلهمراتبهای ماژول سازماندهی خواهند شد.
مکان این سلسلهمراتبها با گزینههای خط فرمان به javac معرفی میشوند که نام آنها معمولاً به "path" ختم میشود، مانند --source-path یا --class-path. همچنین به عنوان یک قاعده کلی، گزینههای مسیری که نام آنها شامل کلمه module است، مانند --module-path، برای تعیین سلسلهمراتبهای ماژول استفاده میشوند، اگرچه برخی از گزینههای مسیر مرتبط با ماژول اجازه میدهند یک سلسلهمراتب بسته برای هر ماژول به طور جداگانه تعیین شود. تمام گزینههای مسیر دیگر برای تعیین سلسلهمراتبهای بسته استفاده میشوند.
هنگامی که یک فایل JAR در مسیر کلاس کاربر دارای ویژگی مانیفست Class-Path باشد و فایل(های) JAR مشخصشده وجود داشته باشند، آنها به طور خودکار پس از فایل JAR مربوطه در مسیر کلاس کاربر درج میشوند. این قاعده همچنین به صورت بازگشتی برای هر فایل JAR جدیدِ یافتشده اعمال میشود. برای جزئیات بیشتر به مشخصات فایلهای JAR (JAR File Specification) مراجعه کنید.
سلسلهمراتب بسته (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 (دایرکتوری خروجی کلاس، دایرکتوری خروجی منبع و دایرکتوری خروجی هدر بومی) همگی هنگامی که چندین ماژول در حال کامپایل هستند، در یک سلسلهمراتب ماژول سازماندهی خواهند شد.
سلسلهمراتب منبع ماژول (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 را میتوان ارائه داد که هر کدام از شکل الگوی ماژول یا شکل مختص ماژول استفاده میکنند، مشروط به محدودیتهای زیر:
- شکل الگوی ماژول حداکثر یک بار میتواند استفاده شود.
- شکل مختص ماژول برای هر ماژول دادهشده حداکثر یک بار میتواند استفاده شود.
اگر شکل مختص ماژول برای هر ماژولی استفاده شود، مسیر جستجوی مرتبط با آن بر هر مسیری که ممکن بود از شکل الگوی ماژول استنتاج شود ارجحیت دارد و آن را رونویسی میکند.
شکل مختص ماژول (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 و غیره...
آکولادها ممکن است تودرتو باشند.
این قاعده برای تمام کاربردهای اینچنینی از آکولاد اعمال میشود.
- •
- هر بخش باید حداکثر یک ستاره (*) داشته باشد. اگر بخشی حاوی ستاره نباشد، فرض میشود که نویسه جداکننده فایل و یک ستاره به انتهای آن اضافه شده است.
برای هر ماژول 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 پشتیبانی مستقیمی از پردازش حاشیهنویسی ارائه میدهد.
رابط برنامهنویسی (API) برای پردازشگرهای حاشیهنویسی در بستهها و زیربستههای javax.annotation.processing و javax.lang.model تعریف شده است.
نحوه کارکرد پردازش حاشیهنویسی (How Annotation Processing Works)
پردازش حاشیهنویسی با استفاده از گزینهای برای پیکربندی پردازش حاشیهنویسی مانند -processor، --processor-path، --processor-module-path یا با فعالسازی صریح پردازش با گزینههای -proc:full یا -proc:only درخواست میشود. پردازش حاشیهنویسی با استفاده از گزینه -proc:none غیرفعال میشود.
اگر پردازش حاشیهنویسی درخواست شود، کامپایلر به دنبال پردازشگرهای حاشیهنویسی موجود میگردد.
مسیر جستجو را میتوان با گزینه -processorpath مشخص کرد. اگر مسیری مشخص نشود، از مسیر کلاس کاربر استفاده میشود. پردازشگرها با استفاده از فایلهای پیکربندی ارائهدهنده سرویس به نام META-INF/services/javax.annotation.processing.Processor در مسیر جستجو پیدا میشوند. این فایلها باید حاوی نام پردازشگرهای حاشیهنویسی مورد استفاده باشند که در هر سطر یک نام ذکر شده است. همچنین، پردازشگرها را میتوان به صراحت با استفاده از گزینه -processor مشخص کرد.
پس از بررسی فایلهای منبع و کلاسهای موجود در خط فرمان برای تعیین حاشیهنویسیهای موجود، کامپایلر از پردازشگرها پرسوجو میکند تا مشخص کند چه حاشیهنویسیهایی را پردازش میکنند. هنگامی که تطابقی یافت شد، پردازشگر فراخوانی میشود. یک پردازشگر میتواند حاشیهنویسیهایی را که پردازش میکند تصاحب (claim) کند، که در این صورت تلاش دیگری برای یافتن پردازشگرها برای آن حاشیهنویسیها انجام نمیشود. پس از اینکه همه حاشیهنویسیها تصاحب شدند، کامپایلر به دنبال پردازشگرهای اضافی نمیگردد.
اگر پردازشگری فایلهای منبع جدیدی تولید کند، دور دیگری از پردازش حاشیهنویسی رخ میدهد: هر فایل منبع تازه تولیدشده بررسی میشود و حاشیهنویسیها مانند قبل پردازش میشوند. هر پردازشگری که در دورهای قبلی فراخوانی شده باشد، در تمام دورهای بعدی نیز فراخوانی میشود. این فرآیند تا زمانی که هیچ فایل منبع جدیدی تولید نشود ادامه مییابد.
پس از دورهای که هیچ فایل منبع جدیدی تولید نمیشود، پردازشگرهای حاشیهنویسی برای آخرین بار فراخوانی میشوند تا فرصت تکمیل کارهای باقیمانده را داشته باشند. در نهایت، مگر اینکه از گزینه -proc:only استفاده شده باشد، کامپایلر فایلهای منبع اصلی و تمام فایلهای تولیدشده را کامپایل میکند.
اگر از پردازشگر حاشیهنویسی استفاده میکنید که فایلهای منبع اضافی را برای گنجاندن در کامپایل تولید میکند، میتوانید یک ماژول پیشفرض را برای فایلهای تازه تولیدشده مشخص کنید، تا زمانی که اعلان ماژول نیز تولید نشده است استفاده شود. در این حالت، از گزینه --default-module-for-created-files استفاده کنید.
محیط کامپایل و محیط زمان اجرا (Compilation Environment and Runtime Environment)
تعاریف موجود در فایلهای منبع و فایلهای کلاس قبلاً کامپایلشده توسط javac در یک محیط کامپایل تحلیل میشوند که متمایز از محیط زمان اجرا مورد استفاده برای اجرای خود javac است. اگرچه شباهت عمدی بین بسیاری از گزینههای javac و گزینههای همنام برای راهانداز جاوا مانند --class-path، --module-path و غیره وجود دارد، درک این نکته مهم است که به طور کلی گزینههای javac فقط بر محیطی که فایلهای منبع در آن کامپایل میشوند تأثیر میگذارند و بر عملکرد خود javac تأثیری ندارند.
تمایز بین محیط کامپایل و محیط زمان اجرا هنگام استفاده از پردازشگرهای حاشیهنویسی بسیار حائز اهمیت است. اگرچه پردازشگرهای حاشیهنویسی عناصری (تعاریفی) را پردازش میکنند که در محیط کامپایل وجود دارند، خود پردازشگر حاشیهنویسی در محیط زمان اجرا اجرا میشود. اگر پردازشگر حاشیهنویسی وابستگیهایی به کتابخانههایی داشته باشد که در ماژولها نیستند، این کتابخانهها را میتوان همراه با خود پردازشگر حاشیهنویسی در مسیر پردازشگر قرار داد. (گزینه --processor-path را ببینید.) اگر پردازشگر حاشیهنویسی و وابستگیهای آن در ماژولها هستند، باید به جای آن از مسیر ماژول پردازشگر استفاده کنید. (گزینه --processor-module-path را ببینید.) هنگامی که این موارد ناکافی باشند، ممکن است نیاز به پیکربندی بیشتر محیط زمان اجرا باشد. این کار را میتوان به دو روش انجام داد:
- 1.
- اگر javac از خط فرمان فراخوانی شود، گزینهها را میتوان با قرار دادن پیشوند -J به زمان اجرای زیرین ارسال کرد.
- 2.
- میتوانید مستقیماً یک نمونه از ماشین مجازی جاوا را راهاندازی کنید و از گزینههای خط فرمان و 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 و نگارشهای جدیدتر، نمیتوانید از هیچ گزینهای که برای پیکربندی مسیر کلاس bootstrap در نظر گرفته شده است استفاده کنید. این شامل تمام گزینههای زیر میشود:
- •
- -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") به دست آورد. این یک شیء با عملکرد معادل ابزار خط فرمان برمیگرداند.
- Legacy API برای javac
- این API فقط برای سازگاری عقبروی حفظ شده است. تمام کدهای جدید باید از Java Compiler API یا ToolProvider API استفاده کنند.
نکته: تمام کلاسها و متدهای دیگر موجود در بستهای با نامهایی که با com.sun.tools.javac شروع میشوند (زیربستههای com.sun.tools.javac) کاملاً داخلی هستند و در هر زمان ممکن است تغییر کنند.
مثالهای استفاده از کلیدهای -XLINT (EXAMPLES OF USING -XLINT KEYS)
- cast
- درباره تبدیل نوعهای غیرضروری و اضافی هشدار میدهد، برای مثال:
String s = (String) "Hello!"
- classfile
- درباره مسائل مربوط به محتویات فایل کلاس هشدار میدهد.
- deprecation
- درباره استفاده از موارد منسوخشده هشدار میدهد. برای مثال:
-
java.util.Date myDate = new java.util.Date(); int currentDay = myDate.getDay();
متد java.util.Date.getDay از زمان JDK 1.1 منسوخ شده است.
- dep-ann
- درباره مواردی که با کامنت Javadoc با تگ @deprecated مستند شدهاند، اما فاقد حاشیهنویسی @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) بررسی میکند و در صورت وجود، پیام هشداری ارائه میدهد. حالتهای افتادن، مواردی در یک بلوک switch به جز آخرین مورد هستند که کد آنها شامل دستور break نیست و اجازه میدهد اجرای کد از آن حالت به حالت بعدی بیفتد. برای مثال، کد پس از برچسب 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 همراه با شماره خط مورد نظر صادر میکند.
- finally
- درباره بندهای finally که نمیتوانند به طور معمول کامل شوند هشدار میدهد، برای مثال:
-
public static int m() { try { throw new NullPointerException(); } catch (NullPointerException e) { System.err.println("Caught NullPointerException."); return 1; } finally { return 0; } }کامپایلر برای بلوک finally در این مثال یک هشدار تولید میکند. هنگامی که متد int فراخوانی میشود، مقدار 0 را برمیگرداند. یک بلوک finally هنگام خروج از بلوک try اجرا میشود. در این مثال، هنگامی که کنترل به بلوک catch منتقل میشود، متد int خارج میشود. با این حال، بلوک finally باید اجرا شود، بنابراین حتی با اینکه کنترل به خارج از متد منتقل شده بود، اجرا میشود.
- options
- درباره مسائل مربوط به استفاده از گزینههای خط فرمان هشدار میدهد. به بخش کامپایل برای نگارشهای قبلی پلتفرم مراجعه کنید.
- 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، کامپایلر پارامتر صوری String... s را به پارامتر صوری String[] s ترجمه میکند، آرایهای که با پارامتر صوری متد ClassWithOverridingMethod.varargsMethod مطابقت دارد. در نتیجه، این مثال کامپایل میشود.
- path
- درباره عناصر مسیر نامعتبر و دایرکتوریهای مسیر ناموجود در خط فرمان (با توجه به مسیر کلاس، مسیر منبع و سایر مسیرها) هشدار میدهد. چنین هشدارهایی را نمیتوان با حاشیهنویسی @SuppressWarnings نادیده گرفت. برای مثال:
- لینوکس و مکاواس: javac -Xlint:path -classpath /nonexistentpath Example.java
- ویندوز: javac -Xlint:path -classpath C:\nonexistentpath Example.java
- processing
- درباره مسائل مربوط به پردازش حاشیهنویسی هشدار میدهد. کامپایلر هنگامی که کلاسی دارای حاشیهنویسی باشد و از پردازشگر حاشیهنویسی استفاده کنید که نتواند آن نوع حاشیهنویسی را مدیریت کند، این هشدار را تولید میکند. برای مثال، کد زیر یک پردازشگر حاشیهنویسی ساده است:
-
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) { ... }
void countElements(List<?> l) { ... }
- serial
- درباره عدم وجود تعاریف serialVersionUID در کلاسهای سریالپذیر هشدار میدهد. برای مثال:
-
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 را به صراحت تعریف نکند، محیط زمان اجرای سریالسازی مقدار پیشفرضی برای 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();
- 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 و غیرعمومی هشداری تولید نمیکنند.
- try
- درباره مسائل مربوط به استفاده از بلوکهای try، از جمله دستورات try-with-resources هشدار میدهد. برای مثال، هشداری برای دستور زیر تولید میشود زیرا منبع ac تعریفشده در بلوک try استفاده نشده است:
-
try ( AutoCloseable ac = getResource() ) { // do nothing}
- unchecked
- جزئیات بیشتری برای هشدارهای تبدیل بررسینشده که توسط مشخصات زبان جاوا الزامی شدهاند ارائه میدهد، برای مثال:
-
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>) است انتساب داده شود. با این حال، کامپایلر همچنان این انتساب را مجاز میداند. باید این انتساب را برای حفظ سازگاری عقبروی با نگارشهایی از Java SE که از جنریکها (generics) پشتیبانی نمیکردند، مجاز بداند. به دلیل پاکسازی نوع، هر دو List<Number> و List<String> به List تبدیل میشوند. در نتیجه، کامپایلر انتساب شیء l را که نوع خام 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); } } }یک نوع غیرقابل تصدیق مجدد، نوعی است که اطلاعات نوع آن در زمان اجرا به طور کامل در دسترس نیست. کامپایلر هشدار زیر را برای تعریف متد ArrayBuilder.addToList تولید میکند: -
warning: [varargs] Possible heap pollution from parameterized vararg type T
هنگامی که کامپایلر با یک متد varargs مواجه میشود، پارامتر صوری varargs را به یک آرایه ترجمه میکند. با این حال، زبان برنامهنویسی جاوا اجازه ایجاد آرایههایی از انواع پارامتریشده را نمیدهد. در متد ArrayBuilder.addToList، کامپایلر پارامتر صوری T... را به پارامتر صوری T[]، یعنی یک آرایه ترجمه میکند. اما به دلیل پاکسازی نوع، کامپایلر پارامتر صوری varargs را به عناصر Object[] تبدیل مینماید. در نتیجه، احتمال بروز آلودگی هیپ وجود دارد.
| 2026 | JDK 26.0.2.1 |