Understanding Java Annotations: Meaning, Usage, and Creation


Java වල Annotations: අර්ථය, භාවිතය සහ නිර්මාණය
ආයුබෝවන්! ඔබ Java සමඟ වැඩ කරන විට, කේතයේ තැනින් තැන @Override
, @Deprecated
වගේ @
සලකුණකින් පටන්ගන්නා යමක් දැක ඇති. මේවා තමයි Java Annotations (ඇනොටේෂන්) කියන්නේ. සරලව කිව්වොත්, මේවා හරියට අපේ කේතයට (ක්ලාස්, මෙතඩ්, ෆීල්ඩ් වගේ දේවල් වලට) අලවන ලේබල් (labels) හෝ ටැග් (tags) වගෙයි.
Annotations කෙලින්ම කේතය ක්රියාත්මක වන විදිහ වෙනස් කරන්නේ නැහැ. ඒ වෙනුවට, ඒවා කේතය පිළිබඳව අමතර තොරතුරු (Metadata ) ලබා දෙනවා. මේ තොරතුරු Compiler එකට, Build Tools වලට, Frameworks වලට (උදා: Spring, JUnit), සහ Runtime එකේදී Reflection හරහා ප්රයෝජනයට ගන්න පුළුවන්.
අපි දැන් Java Annotations ගැන විස්තරාත්මකව බලමු.
Java Annotation වල අරමුණු (Java Annotation Purposes)
Annotations ප්රධාන වශයෙන් අරමුණු කිහිපයක් සඳහා යොදාගන්නවා:
Compiler එක සඳහා තොරතුරු:
වැරදි හඳුනාගැනීමට උදව් කිරීම (උදා:
@Override
annotation එක මගින් method එකක් හරියටම override වෙනවද බලනවා).Compiler warnings යටපත් කිරීම (උදා:
@SuppressWarnings
මගින් අනවශ්යයි කියා සිතන warning එකක් නොපෙන්වා සිටීමට කියනවා).කේත කොටසක් යල් පැන ගිය බව (outdated) සලකුණු කිරීම (උදා:
@Deprecated
).
Compile-time සහ Deployment-time සැකසීම:
- Software build tools (Maven, Gradle වගේ) හෝ විශේෂ Annotation Processors වලට annotations පාවිච්චි කරලා කේත (code generation), XML වැනි configuration files, හෝ වෙනත් දේවල් ස්වයංක්රීයව උත්පාදනය කරන්න පුළුවන්. (උදා: Lombok library එක annotations වලින් getters, setters හදනවා).
Runtime සැකසීම:
Frameworks (Spring, Jakarta EE, JUnit වැනි) runtime එකේදී annotations කියවලා (Reflection හරහා) ඒ අනුව වැඩසටහනේ හැසිරීම වෙනස් කරනවා. උදාහරණයක් ලෙස:
Dependency Injection කිරීම (
@Autowired
- Spring වල).Web requests නිශ්චිත methods වලට map කිරීම (
@GetMapping
- Spring MVC).Test cases හඳුනාගැනීම (
@Test
- JUnit).Object එකක් database table එකකට map කිරීම (
@Entity
- JPA).
Reflection භාවිතයෙන් Annotations ලබාගැනීම (Accessing Java Annotations via Java Reflection)
Annotation එකක් නිර්මාණය කිරීමේදී එහි RetentionPolicy
එක RUNTIME
ලෙස සකසා ඇත්නම්, වැඩසටහන ක්රියාත්මක වන විට (at runtime) එම annotation එක සහ එහි දත්ත ලබාගැනීමේ හැකියාව තියෙනවා. මේ සඳහා Java Reflection භාවිතා කරනවා.
Reflection කියන්නේ Java වැඩසටහනකට, එය ක්රියාත්මක වන විට තමන් ගැනම (තමන්ගේ classes, methods, fields, annotations ගැන) තොරතුරු සොයා බැලීමේ හැකියාවයි.
Reflection API එක භාවිතා කරලා:
යම් class එකක, method එකක, හෝ field එකක නිශ්චිත annotation එකක් තියෙනවද කියා පරීක්ෂා කරන්න (
isAnnotationPresent()
).Annotation එකක් තියෙනවා නම්, ඒ annotation object එක ලබාගෙන එහි elements වල අගයන් (values) කියවන්න (
getAnnotation()
).
මේ ක්රමය Frameworks විසින් බහුලව භාවිතා කරනවා annotations මත පදනම්ව තීරණ ගැනීමට.
Annotation මූලික කරුණු (Annotation Basics)
Annotation එකක් හැමවිටම
@
සලකුණෙන් පටන් ගන්නවා.ඊට පසුව annotation type එකේ නම සඳහන් වෙනවා (උදා:
@Override
,@Test
).Annotations වලට elements (අංග) තියෙන්න පුළුවන් (හරියට method parameters වගේ).
Annotation Elements (අංග/Elements)
Annotation එකකට අමතර දත්ත ලබාදීමට elements භාවිතා කරන්න පුළුවන්. මේවා key-value යුගල වගේ ක්රියාත්මක වෙනවා.
Syntax:
@AnnotationName(elementName1 = value1, elementName2 = value2)
value
නමැති විශේෂ Element එක: Annotation එකේ තියෙන්නේvalue
නමින් එකම element එකක් විතරක් නම්, එය භාවිතා කරන විටvalue =
කෑල්ල ලියන්නේ නැතුව කෙලින්ම අගය දෙන්න පුළුවන්.උදාහරණ:
@SuppressWarnings("unchecked")
(මෙහිදීvalue = "unchecked"
ලෙස නොලියා කෙටියෙන් ලියලා තියෙන්නේ).උදාහරණ:
@MyAnnotation(value = "some data")
(වෙනත් element නමක් හෝ elements කිහිපයක් ඇති විට).
Default Values: Annotation එක නිර්වචනය කිරීමේදී elements වලට default අගයන් ලබා දෙන්න පුළුවන්. එසේ කළ විට, annotation එක භාවිතා කිරීමේදී එම element එකට අගයක් නොදුන්නොත් default අගය ගැනෙනවා.
Annotation Placement (ස්ථානගත කිරීම)
Annotations විවිධ කේත කොටස් මත තබන්න පුළුවන්:
Classes, Interfaces, Enums (
@Entity
,@Component
)Methods (
@Override
,@Test
,@GetMapping
)Fields (Instance variables) (
@Autowired
,@Id
)Method Parameters (
@RequestParam
,@PathVariable
)Constructors (
@Autowired
)Local Variables
Package declarations (
package-info.java
file එකේ)Type parameters and type uses (Advanced)
Java වල ඇති Built-in Annotations
Java Development Kit (JDK) එකෙන්ම අපිට බහුලව භාවිතා වන annotations කිහිපයක් සපයනවා:
@Deprecated
:මේකෙන් සලකුණු කරන්නේ යම් class එකක්, method එකක්, හෝ field එකක් යල් පැන ගිය (outdated) බව සහ එය තවදුරටත් භාවිතා නොකළ යුතු බවයි.
Compiler එක,
@Deprecated
ලෙස සලකුණු කළ යමක් භාවිතා කරන තැනකදී warning එකක් දෙනවා.සාමාන්යයෙන් යමක් deprecated කරන්නේ ඊට වඩා හොඳ විකල්පයක් හඳුන්වා දී ඇති විට හෝ අනාගතයේදී එය ඉවත් කිරීමට නියමිත විටයි.
@Override
:මේකෙන් compiler එකට කියන්නේ, මෙම annotation එක යෙදූ method එක superclass එකකින් හෝ interface එකකින් එන method එකක් override (ප්රතිස්ථාපනය) කිරීමට අදහස් කරන බවයි.
ඔබ method නම හෝ parameters වැරදියට යතුරු ලියනය කළහොත්, compiler එකට
@Override
නිසා දෝෂයක් පෙන්වා දීමට පුළුවන් වෙනවා. මේක හරිම ප්රයෝජනවත්!
@SuppressWarnings
:Compiler එකෙන් එන යම් නිශ්චිත වර්ගයක warning එකක් නොසලකා හරින්න කියලා compiler එකට උපදෙස් දෙන්න මේක පාවිච්චි කරනවා.
උදාහරණ:
@SuppressWarnings("unchecked")
(Generics සම්බන්ධ warning),@SuppressWarnings("deprecation")
(Deprecated කේත භාවිතය සම්බන්ධ warning).මේක අවශ්යම තැනක, හේතුව හරියටම දැනගෙන විතරක් පාවිච්චි කරන්න ඕන. Warning එකක් suppress කරනවා කියන්නේ යම් අවදානමක් ගන්නවා කියන එකයි.
@Contended
(Java 8+):- මේක ටිකක් advanced annotation එකක්. Concurrent programming වලදී "false sharing" කියන performance ගැටළුව අඩු කරන්න JVM එකට ඉඟියක් දෙන්න පාවිච්චි කරනවා. JVM එක මේ annotation එක තියෙන field එක වටේ අමතර ඉඩක් (padding) තබන්න පුළුවන්. සාමාන්ය යෙදුම් වලදී මෙය අවශ්ය වෙන්නේ කලාතුරකින්.
තමන්ගේම Annotations නිර්මාණය කිරීම (Creating Your Own Java Annotations)
Java වලින් එන annotations වලට අමතරව, අපිට අපේම අවශ්යතා වලට ගැලපෙන annotations හදාගන්නත් පුළුවන්.
Syntax: Annotation එකක් define කරන්නේ
@interface
කියන keyword එක පාවිච්චි කරලා (හරියටclass
හෝinterface
වගේ).public @interface MyCustomAnnotation { // Annotation elements go here }
Elements නිර්වචනය: Annotation එක ඇතුළේ elements හදන්නේ method declarations වගේ. හැබැයි ඒවට parameters දෙන්න බෑ. Method එකේ return type එක තමයි element එකේ data type එක වෙන්නේ (මේවා primitives, String, Class, enum, වෙනත් annotation, හෝ මේ වර්ග වල array එකක් වෙන්න ඕන).
public @interface CodeInfo { String author() default "Unknown"; // Default value එකක් සමඟ int version(); String description(); }
Custom Annotation උදාහරණයක්
අපි උඩ හදපු @CodeInfo
annotation එක පාවිච්චි කරන හැටි බලමු:
@CodeInfo(
author = "Nalin Perera",
version = 2,
description = "This class handles user authentication."
)
public class Authenticator {
@CodeInfo(version = 1, description = "Authenticate user method")
public boolean authenticate(String username, String password) {
// Authentication logic here...
return true;
}
}
Meta-Annotations (Annotation පිළිබඳ Annotations)
අපි හදන custom annotation එකක හැසිරීම පාලනය කරන්න, ඒ annotation definition එක උඩින් තවත් annotations යොදන්න පුළුවන්. මේවට කියන්නේ Meta-Annotations කියලා. ප්රධාන Meta-Annotations 4ක් තියෙනවා:
@Retention
:මේකෙන් කියන්නේ annotation එකේ තොරතුරු කොච්චර කාලයක් (කුමන මට්ටමක් දක්වා) රඳවා තබාගන්න ඕනෙද කියන එක.
RetentionPolicy.SOURCE
: Compiler එක විතරක් පාවිච්චි කරයි,.class
file එකට යන්නේ නෑ. Annotation processors වලට ප්රයෝජනවත්.RetentionPolicy.CLASS
:.class
file එකේ තියේවි, නමුත් runtime එකේදී Reflection වලින් ගන්න බෑ (මේක default එක).RetentionPolicy.RUNTIME
:.class
file එකේ තියෙනවා, runtime එකේදී Reflection වලින් access කරන්නත් පුළුවන්. Frameworks එක්ක පාවිච්චි කරන ගොඩක් custom annotations වලට මේක යොදනවා.
@Target
:මේකෙන් කියන්නේ හදන annotation එක තියන්න පුළුවන් කේතයේ මොන වගේ තැන්වලද (ඉලක්ක) කියන එක.
ElementType.TYPE
(class, interface, enum)ElementType.METHOD
ElementType.FIELD
(instance variable)ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
තවත් කිහිපයක් තියෙනවා. ඉලක්ක එකකට වඩා දෙන්නත් පුළුවන්. උදා:
@Target({ElementType.METHOD, ElementType.TYPE})
.
@Inherited
:- මේක class එකක් මත යොදන annotation එකකට විතරයි අදාළ වෙන්නේ. මේක දැම්මොත්, superclass එකේ තියෙන මේ annotation එක subclass එකටත් උරුම වෙනවා (inherit වෙනවා).
@Documented
:- මේක annotation එකක තිබුනොත්, ඒ annotation එක භාවිතා කරලා තියෙන තැන් ගැන Javadoc හදද්දී, ඒ documentation එකට මේ annotation එකත් ඇතුලත් කරනවා.
Custom Annotation එකක Meta-Annotations යෙදීම:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) // Runtime එකේදීත් තොරතුරු ඕන
@Target(ElementType.TYPE) // Class, Interface, Enum වලට විතරයි දාන්න පුළුවන්
@Documented
@Inherited
public @interface MyFrameworkAnnotation {
String value();
}
අවසාන වශයෙන්
Java Annotations කියන්නේ නූතන Java ලෝකයේ ඉතා වැදගත් අංගයක්. Compiler එකට, build tools වලට, frameworks වලට අමතර තොරතුරු ලබා දෙන්න, කේතය පැහැදිලි කරගන්න, සහ boilerplate code අඩු කරන්න මේවා උදව් වෙනවා. @Override
වගේ සරල built-in annotation එකක ඉඳන්, Spring Framework එකේ තියෙන සංකීර්ණ annotations දක්වා මේවා විවිධ මට්ටම් වලින් අපේ coding ජීවිතය පහසු කරනවා. තමන්ගේම annotations හදන්න ඉගෙන ගැනීමත් Java developer කෙනෙක්ට වටිනා හැකියාවක්.
Subscribe to my newsletter
Read articles from Uthsara Basnayake directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
