# فناوری جاوا > برنامه‌نویسی جاوا > Java SE : نگارش استاندارد جاوا >  annotation  در جاوا

## kobari

دوستانی که در باره کاربرد و نحوه استفاده از annotation   در جاوا اطلاعاتی دارند لطف کنند و مطالبی را در این باره ارائه دهند.

----------


## javaphantom

این سوال خوبی بود. من چندبار این سوال رو به بهانه های گوناگون مطرح کردم ولی هیچ کس جوابی نداد و فقط بی راه. خوب حالا مثل اینکه خودم باید در مورد بگم.
توصیف حالات و رفتار یک قطعه کد خیلی جاها به درد می خوره. سرعت فهم رو بالا می بره تا اینکه آدم بخواد بیاد و اون قسمت رو ردیابی کنه تا بتونه منطق اونو در بیاره. ما با این مسئله خیلی جاها درگیر بودیم نمونه بارزش comment ها که در اکثر برنامه هایی که بصورت حرفه ای کد زده شده اند می شه مشاهده کرد. برای مثال 
public void doSomting(); //do someting for you
comment گزاشته شده برای کسی که کد رو نگاه می کنه حاوی یکسری اطلاعات هست یا به زبانی دیگر بصورت خیلی خلاصه توصیف رفتار این Method رو می کنه. این قسمت از برنامه با علامت // نشان داده شده هنگام compile هیچ اثری از خودش بجا نمی زاره در اصل کامپایلر از اون می گذره ولی همانطور که توضیح دادم اثر خودشم گذاشته منتها برای کسی که کد رو می بینه.
توی تمام زبانها چیز به عنوان comment وجود داشته و داره. در جاوا ۱.۵ و به بالا بحثی بوجود اومد به نام annotation که در زبان C#‎ با نام attribute می باشدکه به این دسته اطلاعات metadata گفته می شود که به معنای اطلاعاتی هستند که اطلاعات دیگری را توصیف می کنند. اما در جاوا که بحث ما هست به سه دسته کلی تقسیم می شن.
اطلاعاتی رو فقط مخصوص کامپایلر به همراه دارند
می توانند هنگام کامپایل کردن تولید یک سری کد شوند که در جایی مثل یک فایل xml حاوی یک سری اطلاعات باشند.
از همه مهمتر می توانند هنگام زمان اجرا یا همان runtime مورد استفاده قرار بگیرند.

من برای اینکه بیشتر وارد جزییات بشم مجبورم به سراغ کد زدن برم تا بتونید بیشتر با مسئله آشنا بشید. برای همین اول چند مثال ساده می زنم که حتما با هاش برخود داشته اید. یکسری از این annotation هایی که بیشتر وقتها ما توی برنامه ها می بینیم و از اونها استفاده می کنیم annotation های هستند که فقط برای کامپایلر داری مفهوم می باشند مانند
Override@
Deprecated@
که هر کدام هنگام کامپایل برای کامپایلر دارای مفهموم خاصی هستند.

اما کلا یک annotation چگونه ساخته می شه و چه خاصیت هایی داره و کاربرد آن چگونه است.
برای ساختن یک annotation به صورت زیر عمل می کنیم
public @intrface MyAnnotation {
{
zzzzzzzzzzz
همانطور که می بینید ساختن یک annotation مانند یک interface هست با تفاوت هما علامت @ که نشان دهنده این است ما یک annotation داریم.
خواصی که annotation ها دارند اینکه به هیچ عنوان خاصیت ارث بری را ندارند هر چند که بصورت automatic از کلاس Annotation ارث می گیرند.
برای تعریف کردن یا ساخت annotation می توان از annotation های دیگر هم استفاده کرد.
اما داخل این کدی که نوشته شد چی باید باشد.
کلا داخل یک annotation مانند یک Mehtod می باشد و می توان بصورت field آنها را تعریف کرد.
public @interface MyAnnotation {
private String name();
private int age();
{
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz  zzzzz
همانطور که در تکه کد بالا می بینید name و age هر دو field های MyAnnotation هستند.
اما برای اینکه به این دو مقداری داده بشه بصورت زیر عمل می کنیم
@MyAnnotation(name="babak",age = 28)
public static void main(String[] st){}
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
توجه کنید که علامت @ باید پشت MyAnnotation قرار بگیره ولی از اونجایی که من نمی تونم با این ادیتور خوب کار کنم به این شکل درومده
برای آشنایی بیشتر با annotation ها و کاربرد آنها در هنگام runtime در صورتی که استقبال بشه توضیح می دم و مثال می زنم.
چاکس

----------


## saeedIRHA

Method های داخل Annotation هم مثل Interface همه Abstract
تعریف میشن و باید Override بشن ؟؟؟

----------


## javaphantom

> Method های داخل Annotation هم مثل Interface همه Abstract
> تعریف میشن و باید Override بشن ؟؟؟


همانطور که اشاره شده ما تمام فیلدها رو در بدنه annotation مانند یک method تعریف می کنیم
خود جاوا اونو برامون پیاده سازه  می کنه. برای بیشتر روشنتر شدن مسئله همانطور که گفته شد هر annotation کی تعریف می شه بصورت automatic از کلاس Annotation  ارث می بره. پس به سراغ کلاس پدر می ریم تا ببینم داستان کار چه جوری هست و ما واقعا از annotation درست کردن چه هدفی داریم.

در package ی که الان به آن اشاره می شه java.lang.annotation
public interface Annotation می باشد که supper کلاس همه annotation ها است که درون این Annotation چهار متدود 
annotationType()
equals()
hashCode()
toString()
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
وجود داره که خود جاوا اینهارو override می کنه.
اگر دقت کرده باشید در مثال قبل من فقط فیلدهای تعریف شده را مقدار دهی کردم.
حالا جلوتر هنگامی کار با annotation هایی که هنگام runtime کار می کنه با مثالی بهتر بهتون نشون می دم که ما دقیقا دنبال چی هستیم و برای چی annotaion تعریف می کنیم و چگونه استفاده می کنیم.

----------


## rezaTavak

دوست عزیز بالای همین ویرایشگر یک آیکن # وجود دارد که با زدن آن دو [ code ] , [ / code] ظاهر میشه بین این دو کد خود را قرار دهید. یا اینکه این تگها را خودتان تایپ کنید.

----------


## kobari

> برای آشنایی بیشتر با annotation ها و کاربرد آنها در هنگام runtime در صورتی که استقبال بشه توضیح می دم و مثال می زنم.
> چاکس


ضمن تشکر از توضیحات عالی شما در صورت امکان کمی هم در باره نحوه بکار گیری مثال MyAnnotation در کلاس هایی که می خواهند از اطلاعات این متادیتاها استفاده کنند توضیح دهید. آیا این کلاسها می توانند رفتار خود را بر اساس این اطلاعات تغییر دهند؟ چگونه؟

----------


## javaphantom

با چند یادآوری و چند نکته جدید می ریم سراغ اولین مثال.
یادآوری:
annotation اطلاعاتی هست که اطلاعات دیگری رو توضیح می ده.
به تنهایی بی ارزش هست و برای اینکه کارایی داشته باشه نیاز به یک ابزار داره که به اون ماهیت بده.
از هیج کلاسی ارث نمی گیره ولی بصورت خودکار از intefrace Annotation ارث می بره پس ماهیت اون در آخر بصورت یک object هست.
بصورت یک modifier است که می تونه پشت یک کلاس یا یک متد یا یک فیلد بیاید.
نکته: modifier ها مانند private , public,static,...
برای ساختن annotation می توان از annotation های دیگر هم استفاده کرد.
می توانند در هنگام runtime اثر گذار باشند
می توان برای آنها المان هایی در نظر گرفت و به آنها مقدار دهی کرد.
مثال زیر یک نمونه کامل از تما تعریفات بالا می باشد.
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)

public @interface MyAnnotation {
	String name();
	int age();
} 
همانطور که می بینید برای ساختن این annotation از دو annotation دیگر هم استفاده کردیم که اولی بیانگر این است که این annotation ساخت شده برای یک method می باشد و دومی به این موضوع اشاره می کند که هنگام runtime این annotation مورد استفاده قرار می گیرد.
شامل دو المان می باشد که یکی از نوع String و دیگری از نوع int تا اینجا قبلا هم انجام دادیم اما حالا می خواهیم از این annotation استفاده کنیم.
قبل از ادامه حتما به api Class یک سری بزنید. در این کلاس یعنی Class متدودی وجود دارد به نام getClass که در کلاس Object می باشه  و چون کلاس Class هم از Object ارث گرفته به اون دسترسی داره که کار این method این که هنگام runtime نوع object مورد استفاده شده را بر میگردونه ( اطلاعات بیشتر به عهده خودتان در مورد این API) در پکیجه java.lang می باشد
در package دیگر یعنی java.lang.reflect کلاسی وجود دارد به نام Method که می توان متدود یک کلاس رو در آن ریخت یعنی از نوع Method دیتا تایپ آن می باشد و همچنین خود آین کلاس شامل یک method به نام getAnnotation می باشد که مقدار بازگشتی آن از نوع یک کلاس annotation ی می باشد. (اطلاعات بیشتر به عهده خود خواننده)
 حال به باقی مثال توجه کنید
import java.lang.reflect.*;

public class TestAnnotation {

	@MyAnnotation(name="babak",age=28)
	public void test(String s,int t) {
		System.out.println(s);
		System.out.println(t);
	}

	public static void main(String[] s) {
		try {
			TestAnnotation testAnno = new TestAnnotation();
			Class<? extends Object> cl = testAnno.getClass();
			Method m = cl.getMethod("test",String.class,int.class);
			MyAnnotation ma = m.getAnnotation(MyAnnotation.class);
			testAnno.test(ma.name(),ma.age());
		}catch(Exception e) {
			System.out.println(e);
		}
	}
} 
خروجی شما در آخر کار مقدار babak و  بعد از آن 28 خواهد بود. همانطور که مشاهده می کنید از طریق ابزاری که برای آن در نظر گرفتم توانستم بدون مقدار دادن مستقیم به method ی که تعریف کردم یعنی همان test مقدار خروجی را بگیرم.
دفعه بعد یک مثال خیلی حرفه ای تر خواهم زد.
بعد از اون امیدوارم که سوالات همگی به سمت J2EE مفاهیم اولیه آن و معماری و بعد ejb3 و مفاهیم آن وقدرت annotation ها در آن بجای داشتن حجم عزیم xml فایلها در دیگر framework های غیر استاندارد نظیر spring باشد.

----------


## kobari

> دفعه بعد یک مثال خیلی حرفه ای تر خواهم زد.


خیلی عالی بود. لطفا قبل از اینکه وارد مقوله های پیچیده تر بشی  یک مثال هم روی کاربرد annotation  در property ها بزن .

----------


## unhandled_event

> بعد از اون امیدوارم که سوالات همگی به سمت J2EE مفاهیم اولیه آن و معماری و بعد ejb3 و مفاهیم آن وقدرت annotation ها در آن بجای داشتن حجم عزیم xml فایلها در دیگر framework های غیر استاندارد نظیر spring باشد.


سلام

شاید مهمترین حسن این framework ها امکان Injection  و معرفی نوع کلاسها و  اشیاء و پارامترها برای هر کلاس در زمان  Runtime  خارج از برنامه در فایلهای xml باشه یعنی بدون کامپایل مجدد و ساختن دوباره Jar فایل میشه سیستم در حال کار  رو تغییرات داد اما اگر از Annotation ها داخل کلاس استفاده کنیم مثل ejb 3   با تغییرات پارامترها  دوباره نیاز به کامپایل مجدد و Deploy کردن برنامه پیش میاد برای من جای سواله که آیا سختی استفاده از xml ها رو باید ترجیح داد ( مثل spring ) یا بازگشت به عصر کامپایل مجدد ( که در سیستمهای همیشه آنلاین امکانش نیست) چون بعضی وقتها کل jar file باید تعویض بشه احتمالا اینها باید در ejb 3 پیش بینی شده باشه

----------


## javaphantom

> سلام
> 
> شاید مهمترین حسن این framework ها امکان Injection  و معرفی نوع کلاسها و  اشیاء و پارامترها برای هر کلاس در زمان  Runtime  خارج از برنامه در فایلهای xml باشه یعنی بدون کامپایل مجدد و ساختن دوباره Jar فایل میشه سیستم در حال کار  رو تغییرات داد اما اگر از Annotation ها داخل کلاس استفاده کنیم مثل ejb 3   با تغییرات پارامترها  دوباره نیاز به کامپایل مجدد و Deploy کردن برنامه پیش میاد برای من جای سواله که آیا سختی استفاده از xml ها رو باید ترجیح داد ( مثل spring ) یا بازگشت به عصر کامپایل مجدد ( که در سیستمهای همیشه آنلاین امکانش نیست) چون بعضی وقتها کل jar file باید تعویض بشه احتمالا اینها باید در ejb 3 پیش بینی شده باشه


دقیقا یک بار دیگه این مطلب از طرف یکی دیگر مطرح شد و من هم جواب دادم که در ejb3 استفاده از xml فایل ها و یا همان descriptor ها بصورت optional  می باشد یعنی می توان هم از انها استفاده کرد و هم می توان نکرد. دیگه چی می خوای

----------


## javaphantom

> خیلی عالی بود. لطفا قبل از اینکه وارد مقوله های پیچیده تر بشی  یک مثال هم روی کاربرد annotation  در property ها بزن .


بیشتر توضیح بده مثال بزن که دقیقا کجا رو می خوای

----------


## kobari

> بیشتر توضیح بده مثال بزن که دقیقا کجا رو می خوای


با سلام و عرض معذرت از اینکه به موقع جواب ندادم .

فرض کن که کلاس Person روی شمای یک جدول دیتا بیس بنام person بصورت زیر تعریف شده است :
 
public class Person
{
public String name;
 
public void setName(String nam)
{
this.name = name;
}
 
public String getName()
}
return name;
}
 
}

از آنجائیکه پراپرتی name اطلاعات مریوط به ستون name در جدول person را در خود ذخیر میکند من می خواهم یک سری اطلاعات مربوط به ستون این جدول از قبیل size, datatype, not null و غیره را همراه آن بعنوان متادیتا داشته باشم تا آبژکتهائی که از کلاس Person استفاده می کنند بتوانند این اطلاعات را بدست آورند و بر اساس آنها یک سری کنترل ها را بر روی پراپرتی name اعمال کنند.

----------


## javaphantom

> با سلام و عرض معذرت از اینکه به موقع جواب ندادم .
> 
> فرض کن که کلاس Person روی شمای یک جدول دیتا بیس بنام person بصورت زیر تعریف شده است :
>  
> public class Person
> {
> public String name;
>  
> public void setName(String nam)
> ...


دوست عزیز من سوال شما رو کاملا متوجه شدم. راه حل مناسب JPA یا همان java persistence API می باشد. ما annotationی به نام Column@ داریم که این کار رو برای شما انجام می ده. اما اگر می خواهید این کار رو خودتون انجام بدین من حرفی ندارم سعی می کنم یک نمونه کد بهتون تحویل بدم و لی استاندارد جاوا یا همان API آن یک چیز دیگست.
اگر خواستید و کسی موافق بود بریم سراغ java persistence ها و بحث entity در ejb3

----------


## kobari

> دوست عزیز من سوال شما رو کاملا متوجه شدم. راه حل مناسب JPA یا همان java persistence API می باشد. اگر خواستید و کسی موافق بود بریم سراغ java persistence ها و بحث entity در ejb3


با تشکر، لطفا اگر Java Persistence API در J2SE قابل استفاده می باشد من هم ترجیح میدهم که از استانداردهای جاوا استفاده کنم ، بنا براین بهتر است شما این موضوع را توضیح دهید، در غیر این صورت لطف کنید و همان Annotation را ادامه بدهید.

----------


## javaphantom

بله دوست عزیز JPA یا همان Java Persistence API در J SE و  هم در J EE قابل اجرا می باشد.
دیدی جاوا چه کرده بابا.
خداست.
قبل از اون شما باید به JDBC یا همان Java Database Connectivity آشنایی داشته باشید.

راستشو رو بخواهید متاسفانه من دیگر علاقه ای ندارم که در این فروم بحثهای جدید راه بندازم یا اصلا بخوام به کسی کمکی کنم که البته هم تا حالا نکردم. هر چند که خوشبختانه در این فروم بسیار هستند که بهتر از من و با سوادتر از من هستند.
من هرچی سعی کردم که در این قسمت بحثها بر اساس دلیل و منطق باشه تا به یک نتیجه درست برسیم ولی متاسفانه مسیر توری دیگه انتخاب می شد بطوریکه متهم به جنجالی کردن بحث شدم و حتی به من گفته شد که من دارم دوستی افراد رو توی این فروم بهم می زنم.
خوب دوستی مهمتر است از بحث و علم و کلا java است.
توی این فروم اکثر سوال ها تکراری هست و واقعا چیزه جدیدی به شما نمی ده. البته این نظر من هست. مخصوصا قسمت enterprise که هنوز توی JSP گیر هستند و حتی من ندیم که یک سوال در مورد servlet بشه. حالا چی برسه به JSF یا چیزهای دیگه.
هدف من توی این فروم خیلی بالاتر از این بود که بخوام کد بنویسم و یا چیزی شبیه این. من بیشتر می خواستم که افراد مفهومی کار کنند و بدونند که زبان وسیله هست نه هدف.
جاوا قفط یک مشت کد و کتابخانه نیست که فقط حفظ کنیم و بنویسیم و بعد بگیم ما جاوا بلدیم.
بگذریم.
البته باز من از مدیر این بخش که اسم ایشون رو هم نمی دونم تشکر فراوان دارم که حداقل سانسور نمی کنه و این عمل ایشون واقعا قابل تقدیر از نظر من هست. به شعور دیگران احترام گذاشتن یعنی محترم بودن شعور خود شخص.
شما می تونید از طریق همان email من که دارید در مورد این مسئله بیشتر اصلاعات بگیرد.
من کتاب خوبی به شما معرفی می کنم یا اصلا ممکنه به شما بدم که مطالعه کنید و ازطریق یک مرجع جلو بریم و در مرحله پیاده سازی هم من در خدمتون هستم.
دیگر افراد این فروم اگر نظری در مورد Java Persistence دارند بنویسن ما هم چیز یاد بگیریم.
من در این فروم دیگر سعی می کنم فقط یک خواننده موضوعات و جوابهای دیگران باشم. همین.

----------


## kobari

خوب من خیلی متاسفم که در مورد شما اینگونه قضاوت شده است. من شخصآ مطالب زیادی را از شما یاد گرفتم و بخاطر تمام مطالب مفیدی که در این سایت ارائه کردید تشکر میکنم . در مطالبتان این موضوع کاملآ حس میشه که روش برخوردتان با موضوعات کاملا جنبه آموزشی دارد و تا آنجا که توانستید مسائل را عمیق مورد بررسی قرار دادید و این موضوع نشان از جدیت و تعهد و علاقه شما در ارتباط با جاوا است که جای قدردانی دارد .من بیشتر در پاسخ های شما جنبه تکنیکال دیدم و دیگران بیشتر خیلی سریع و سطحی به سئولات جواب دادند. حالا اگر در بعضی جاها از جملات نا ملایم تری استفاده کردید من فکر میکنم بیشتر بخاطر این است که تاثیر بیشتری در خواننده ایجاد کنید و آنان را در مسیر صحیح تری قرار دهید نه اینکه خدای نکرده قصد جنجال آفرینی را داشته باشید. من فکر میکنم خواننده باید این موضوع را در نظر بگیرد تا برای کسی که وقت می گذارد و حتی در بعضی جاها بخاطر یافتن پاسخ چندین ساعات مطالعه می کند تا مطالب مفید و علمی از خود در این سایت باقی بگذارد احترام قائل باشد و دیگر به شیوه نوشتن نگارنده کاری نداشته باشد.
دوستان این سایت توجه داشته باشند که در برنامه نویسی اطلاعات درست و به موقع گرانبها ترین چیزی است که بوسیله آن می توان یک برنامه درست و کارا در یک زمان کوتاه نوشت و بدون داشتن آن باید مدتها برای جمع آوری اطلاعات اولیه وقت گذاشت، که این کار باعث طولانی شدن زمان برنامه نویسی و سخت شدن آن میشود. پس حالا که در این سایت افرادی پیدا میشوند تا اطلاعات ما را در ارتباط با یک موضوع خیلی سریع تکمیل کنند ، سعی کنیم حضور آنها را در این سایت حفظ کنیم.

----------

