دانستنی‌ها

Annotation یا حاشیه‌نگاری در جاوا

حاشیه‌نگاری در جاوا برای تولید متادیتا استفاده می‌شود.در جاوا حاشیه‌نگاری به صورت مستقیم در اجرای کد نقشی ندارد هرچند برخی از انوع Annotationها می‌توانند برای این منظور استفاده شوند. Annotationها از نسخه 5 به جاوا اضافه شدند.

اهداف Annotationها در جاوا

حاشیه‌نگاری در جاوا بیشتر برای اهداف زیر استفاده می‌شود :

  • راهنمایی کامپایلر
  • راهنمایی در زمان ایجاد فایل اجرایی
  • راهنمایی در زمان اجرای فایل اجرایی

هنگامی‌‌که از برنامه خروجی اجرایی تهیه می‌کنید ، Annotationها در جاوا می‌توانند در زمان ایجاد فایل اجرایی کاربرد داشته باشند،. فرآیند ایجاد شامل تولید سورس، کامپایل سورس، ایجاد فایل‌های XML، بسته‌بندی فایل‌های کامپایل شده به JAR فایل‌ها و …

ایجاد نرم‌افزار معمولا با ابزار ساخت اتوماتیک مانند Apache Ant و Apache Maven انجام می‌شود. ممکن است ابزار ساخت، کدهای شما را برای Annotationهای خاص بررسی کند و بر اساس این Annotationها کدی را تولید یا فایلی را ایجاد کند.

معمولا، Annotationهای جاوا بعد از کامپایل در بایت کد باقی نمی‌مانند. با این حال ممکن است Annotationهایی که خودتان تعریف کرده‌اید در زمان اجرا در دسترس باشند و این Annotationها توسط Java Reflection قابل استفاده هستند.

مبانی حاشیه‌نگاری

خط زیر، یکی از کوتاه‌ترین Annotationهایی است که در جاوا نوشته شده است :

@Entity

کاراکتر @ به کامپایلر علامت می‌دهد که این یک Annotation است. نامِ بعد از کاراکتر @، نامِ Annotation است. در مثال بالا،  Entity نامِ Annotation است.

عناصر Annotation

Annotationها در جاوا می‌توانند عناصری داشته باشند که قابل مقداردهی هستند. یک عنصر مانند یک ویژگی یا پارامتر است. مثال زیر را ببنید:

@Entity(tableName = “vehicles”)

در این مثال، Annotation شامل یک عنصر با نام tablename است که با vehicle مقداردهی شده است. عناصر در یک پرانتز باز و بسته بعد از نام Annotation قرار می‌گیرند. اگر Annotationیی عنصری ندارد، نیازی به پرانتز نیست.

یک Annotation می‌تواند شامل چند عنصر باشد. مثال زیر را ببینید :

@Entity(tableName = "vehicles", primaryKey = "id")

در مثال زیر، Annotation شامل یک عنصر است. نام این عنصر value است :

@InsertNew(value = "yes")

وقتی Annotation فقط یک عنصر دارد می‌توان بدون نام بردن از نام عنصر، فقط مقداردهی کنید. در مثال زیر Annotationیی داریم با یک عنصر یک فقط مقدار عنصر ذکر شده است:

@InsertNew("yes")

محل قراردادن Annotationها

Annotationهای جاوا را می‌توان بالای کلاس‌ها، اینترفیس‌ها، متدها، پارامتر متدها، فیلدها و متغیرهای محلی قرار داد. مثال زیر را ببینید:

@Entity

public class Vehicle {

}

Annotation با کاراکتر @ شروع شده است و در ادامه نامِ Annotation آمده است. در این مثال Entity نامِ است. (این Annotation را قبلا من ساخته‌ام و در جاوا معنی خاصی ندارد)

در زیر یک مثال کامل آورده‌ام که Annotation، بالای کلاس، فیلد، متد، پارامتر و متغیر نوشته شده است :

@Entity

public class Vehicle {

    @Persistent

    protected String vehicleName = null;

    @Getter

    public String getVehicleName() {

        return this.vehicleName;

    }

    public void setVehicleName(@Optional vehicleName) {

        this.vehicleName = vehicleName;

    }

    public List addVehicleNameToList(List names) {

        @Optional

        List localNames = names;

        if(localNames == null) {

            localNames = new ArrayList();

        }

        localNames.add(getVehicleName());

        return localNames;

    }

}

Annotationهای توکار در جاوا

جاوا دارای سه Annotation درونی است که برای راهنمایی کامپایلر استفاده می‌شوند.

  • @Deprecated
  • @Override
  • @SuppressWarnings

@Deprecated

این Annotation برای علامت گذاری یک کلاس، متد یا فیلد به عنوان منسوخ شده استفاده می‌شود و معنی آن این است که نباید از این عناصر استفاده کرد. اگر در کدتان از کلاس، متد یا فیلد منسوخ شده استفاده کنید، کامپایلر به شما هشدار می‌دهد.  مثال زیر را ببینید :

@Deprecated

public class MyComponent {

}

در اینجا، استفاده از @Deprecated یاعث می‌شود که این کلاس علامت منسوخ شده به خود بگیرد.

در زمان استفاده از این حاشیه‌نگاری @Deprecated و جهت راهنمایی توسعه دهنده که از چه عنصری به جای عنصر منسوخ استفاده کند، بهتر است از علامت متناظر @deprecated در JavaDoc استفاده کنید و شرح دهید که چرا این عنصر منسوخ شده است و عنصر جایگزین را معرفی کنید.

@Deprecated

/**

  @deprecated Use MyNewComponent instead.

*/

public class MyComponent {

}

@Override

این Annotation در بالای متدها و برای override کردن متد استفاده می‌شود. اگر متدی که override کرده اید با متد اصلی در کلاس پدر همخوانی نداشته باشد، کامپایلر به شما پیغام خطا می‌دهد. در حالت کلی نیازی به استفاده از @Override نیست و به شکل عادی و در صورتیکه متد مورد نظر با همان متد در کلاس پدر همخوانی داشته باشد نیز می‌توان یک متد را override کرد ولی فرض کنیم ما متدی را بدون @Override پیاده‌سازی کرده ایم و یک نفر نام متد را در کلاس پدر تغییر می‌دهد، موردی که اتفاق می افتد این است که متدی که ما پیاده سازی کرده ایم به عنوان یک متد جدید شناخته می‌شود و دیگر متد مورد نظر از کلاس پدر را override نمی‌کند که همین می‌تواند باعث رویداد خطا شود. اما با استفاده از @Override می‌توان با کمک کامپایلر از بروز چنین مشکلاتی جلوگیری کرد.

public class MySuperClass {

    public void doTheThing() {

        System.out.println("Do the thing");

    }

}

public class MySubClass extends MySuperClass{

    @Override

    public void doTheThing() {

        System.out.println("Do it differently");

    }

}

@SupressWarnings

این Annotation این امکان را به کامپایلر می‌دهد که هشدارهای مربوط به یک متد را نادیده بگیرد. برای مثال، اگر یک متد deprecated شده را فراخوانی کنیم و یا یک تبدیل نا امن داشته باشیم، کامپایلر ما را با هشداری آگاه می‌سازد. بوسیله این Annotation به کامپایلر این اجازه را می‌دهیم که هشدارهای مربوطه را سرکوب کند. مثال زیر را ببینید:

@SuppressWarnings

public void methodWithWarning() {

}

Annotationهای خودتان را بسازید

در جاوا این امکان وجود دارد که Annotation‌های مخصوص خودتان را بسازید. Annotationها در فایل های خودشان تعریف می‌شوند مانند کلاس ها یا اینترفیس ها.

@interface MyAnnotation {

    String   value();

    String   name();

    int      age();

    String[] newNames();

}

در این مثال یک Annotation با نام MyAnnotation ساخته شده است که دارای چهار عنصر است. به کلمه کلیدی @interface دقت کنید. این عبارت به کامپایلر جاوا می‌گوید که این تعریف یک Annotation است.

توجه داشته باشید که هر یک از عناصر شبیه به تعریف متدها در اینترفریس است یعنی یک نوع و یک نام دارد. تمام انواع داده در تعریف عناصر Annotationها قابل استفاده است، همچنین می‌توان از نوع آرایه نیز استفاده است ولی استفاده از کلاس ها امکان پذیر نیست.

برای استفاده از Annotationی که در بالا تعریف کرده‌ایم می‌توان به شکل زیر عمل کرد:

@MyAnnotation(

    value="123",

    name="Jakob",

    age=37,

    newNames={"Jenkov", "Peterson"}

)

public class MyClass {

}

همانطور که می‌بینید برای تمام عناصر این Annotation مقداری را تعریف کرده‌ام.

مقدار پیش فرضِ عناصر

برای عناصر می‌توان مقدار پیش فرض تعریف کرد به این معنی که مقداردهی آن عنصر در زمان استفاده اختیاری است. مثال زیر را ببینید :

@interface MyAnnotation {

    String   value() default "";

    String   name();

    int      age();

    String[] newNames();

}

در این مثال، عنصر value در زمان استفاده می‌تواند مقداردهی نشود. وقتی این عنصر مقداردهی نشود مقدار پیش فرض برای آن در نظر گرفته می‌شود.در مثال زیر از حاشیه نگاری MyAnnotation استفاده شده ولی عنصر value مقداردهی نشده است:

@MyAnnotation(

    name="Jakob",

    age=37,

    newNames={"Jenkov", "Peterson"}

)

public class MyClass {

}

@Retention

می‌توانید تعیین کنید Annotationهایی که ایجاد کرده اید در زمان اجرا (Runtime) برای استفاده در Reflection نیز در دسترس باشند. این کار را هم بوسیله ی Annotationیی که برای Annotationها نوشته شده است می‌توانید انجام دهید یعنی @Retention.

مثال زیر را ببینید :

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

@interface MyAnnotation {

    String   value() default "";

}

توجه داشته باشید که این Annotation را باید بالای Annotationیی که ایجاد کرده اید بنویسید.

@Retention(RetentionPolicy.RUNTIME)

این حاشیه نگاری به کامپایلر جاوا و JVM اشاره می‌کند که این Annotation باید در زمان اجرا جهت استفاده توسط reflection در دسترس باشد.

کلاس RetentionPolicy شامل چند مقدارِ قابل استفاده دیگر نیز است :

RetentionPolicy.CLASS به این معنی است که این Annotation فقط در سورس کد قابل استفاده است و در فایل های .class می‌آید ولی در زمان اجرا قابل استفاده نیست. اگر هیچ مقداری را برای پارامترِ این Annotation مشخص نکنید، مقدار  RetentionPolicy.CLASS برای این Annotation به عنوان مقدار پیش فرض در نظر گرفته می‌شود.

RetentionPolicy.SOURCE به این معنی است که این Annotation فقط در سورس برنامه قابل استفاده است و در فایل .class ذخیره نمی‌شود و در زمان اجرا نیز در دسترس نیست. اگر خودتان یک Annotation جهت استفاده در ابزار تولید bytecode بنویسید، می‌توانید از این مقدار استفاده کنید.

@Target

بوسیله این Annotation می‌توان تعیین کرد که Annotationیی که خودتان تولید کرده‌اید برای کدام یک از عناصر جاوا قابل استفاده باشد. مثال زیر را ببینید :

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

@Target({ElementType.METHOD})

public @interface MyAnnotation {

    String   value();

}

در این مثال نشان داده می‌شود که MyAnnotation را فقط می‌توان برای عنصر متد در جاوا استفاده کرد.

پارامتر ElementType  شامل مقادیر زیر است:

ElementType.ANNOTATION_TYPE

ElementType.CONSTRUCTOR

ElementType.FIELD

ElementType.LOCAL_VARIABLE

ElementType.METHOD

ElementType.PACKAGE

ElementType.PARAMETER

ElementType.TYPE

شرح این مقادیر از نام آنها مشخص است.

Annotation_Type : به معنی استفاده از این Annotation  فقط در تولید و تعریف Annotation های سفارشی خودمان است. مانند @Target و @Retentoin.

Type : این مقدار مشخص می‌کند که Annotation تعریف شده برای نوع داده ها قابل استفاده است. نوع داده می‌تواند شامل کلاس، اینترفیس، enum و Annotation باشد.

منبع : http://tutorials.jenkov.com/java/annotations.html

نوشته های مشابه

‫2 دیدگاه ها

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا