מבוא ל- JavaPoet

1. סקירה כללית

במדריך זה נחקור את הפונקציות הבסיסיות של ספריית JavaPoet.

JavaPoet פותח על ידי כיכר, אשר מספק ממשקי API ליצירת קוד מקור Java. זה יכול ליצור סוגים פרימיטיביים, סוגי התייחסות והווריאציות שלהם (כגון מחלקות, ממשקים, סוגים ספורים, מחלקות פנימיות אנונימיות), שדות, שיטות, פרמטרים, ביאורים ו- Javadocs.

JavaPoet מנהל את הייבוא ​​של המחלקות התלויות באופן אוטומטי. הוא גם משתמש בתבנית Builder כדי לציין את ההיגיון ליצירת קוד Java.

2. תלות של Maven

על מנת להשתמש ב- JavaPoet, אנו יכולים להוריד ישירות את קובץ ה- JAR האחרון, או להגדיר את התלות הבאה שלנו pom.xml:

 com.squareup javapoet 1.10.0 

3. מפרט שיטה

ראשית, בואו נעבור את מפרט השיטה. כדי ליצור שיטה, אנו פשוט קוראים methodBuilder () שיטה של MethodSpec מעמד. אנו מציינים את שם השיטה שנוצר כ- חוּט הטיעון של methodBuilder () שיטה.

אנחנו יכולים ליצור כל הצהרה לוגית בודדת המסתיימת במעי הגס למחצה משתמש ב addStatement () שיטה. בינתיים, אנו יכולים להגדיר זרימת בקרה אחת המוגבלת בסוגריים מסולסלים, כגון אחרת לחסום, או ל לולאה, בזרימת בקרה.

הנה דוגמה מהירה - יצירת ה- sumOfTen () שיטה שתחשב את סכום המספרים בין 0 ל -10:

MethodSpec sumOfTen = MethodSpec .methodBuilder ("sumOfTen") .addStatement ("int sum = 0") .beginControlFlow ("for (int i = 0; i <= 10; i ++)") .addStatement ("sum + = i" ). endControlFlow () .build ();

זה יפיק את התפוקה הבאה:

בטל sumOfTen () {int סכום = 0; עבור (int i = 0; i <= 10; i ++) {sum + = i; }}

4. חסימת קוד

אנחנו יכולים גם לעטוף זרם בקרה אחד או יותר והצהרות לוגיות לבלוק קוד אחד:

CodeBlock sumOfTenImpl = CodeBlock. Builder () .addStatement ("int sum = 0") .beginControlFlow ("for (int i = 0; i <= 10; i ++)") .addStatement ("sum + = i"). EndControlFlow () .בניין ();

מה שמייצר:

סכום int = 0; עבור (int i = 0; i <= 10; i ++) {sum + = i; }

אנו יכולים לפשט את ההיגיון הקודם ב- MethodSpec על ידי התקשרות addCode () ומספק את sumOfTenImpl לְהִתְנַגֵד:

MethodSpec sumOfTen = MethodSpec .methodBuilder ("sumOfTen") .addCode (sumOfTenImpl) .build ();

חסימת קוד חלה גם על מפרטים אחרים, כגון סוגים ו- Javadocs.

5. מפרט שדה

לאחר מכן - בואו נחקור את הלוגיקה של מפרט השדה.

על מנת ליצור שדה, אנו משתמשים ב- בּוֹנֶה() שיטת ה- FieldSpec מעמד:

FieldSpec שם = FieldSpec. Builder (String.class, "שם") .addModifiers (Modifier.PRIVATE) .build ();

פעולה זו תיצור את השדה הבא:

שם מחרוזת פרטי;

אנו יכולים לאתחל את ערך ברירת המחדל של שדה על ידי קריאה ל אתחול () שיטה:

FieldSpec defaultName = FieldSpec. Builder (String.class, "DEFAULT_NAME") .addModifiers (Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer ("\" Alice \ "") .build ();

מה שמייצר:

גמר סטטי פרטי פרטי מחרוזת DEFAULT_NAME = "אליס";

6. מפרט פרמטרים

בואו נבדוק כעת את לוגיקת מפרט הפרמטרים.

במקרה שאנחנו רוצים להוסיף פרמטר לשיטה, אנחנו יכולים לקרוא ל- addParameter () בתוך שרשרת הפונקציה קורא את הבנאי.

במקרה של סוגי פרמטרים מורכבים יותר, אנו יכולים לעשות שימוש ParameterSpec בּוֹנֶה:

מחרוזות ParameterSpec = ParameterSpec. Builder (ParameterizedTypeName.get (ClassName.get (List.class), TypeName.get (String.class)), "מחרוזות") .build ();

אנו יכולים להוסיף גם את השינוי של השיטה, כגון פּוּמְבֵּי ו / או סטָטִי:

MethodSpec sumOfTen = MethodSpec .methodBuilder ("sumOfTen") .addParameter (int.class, "number") .addParameter (strings) .addModifiers (Modifier.PUBLIC, Modifier.STATIC) .addCode (sumOfTenImpl) .build ();

כך נראה קוד Java שנוצר:

public static void sumOfTen (int מספר, מחרוזות רשימה) {int sum = 0; עבור (int i = 0; i <= 10; i ++) {sum + = i; }}

7. סוג מפרט

לאחר בחינת הדרכים לייצור שיטות, שדות ופרמטרים, בואו נסתכל על מפרט הסוג.

כדי להכריז על סוג, נוכל להשתמש ב- TypeSpec שיכולים לבנות מחלקות, ממשקים וסוגים ספורים.

7.1. יצירת כיתה

על מנת ליצור כיתה, אנו יכולים להשתמש ב- classBuilder () שיטת ה- TypeSpec מעמד.

אנו יכולים גם לציין את השינויים שלו, למשל, פּוּמְבֵּי ו סופי משתני גישה. בנוסף לשינויים בכיתות, אנו יכולים גם לציין שדות ושיטות באמצעות כבר הוזכר FieldSpec ו MethodSpec שיעורים.

ציין זאת הוסף שדה() ו addMethod () שיטות זמינות גם בעת יצירת ממשקים או מחלקות פנימיות אנונימיות.

בואו נסתכל על הדוגמה הבאה לבניית כיתות:

TypeSpec person = TypeSpec .classBuilder ("אדם") .addModifiers (Modifier.PUBLIC) .addField (שם) .addMethod (MethodSpec .methodBuilder ("getName") .addModifiers (Modifier.PUBLIC). מחזיר (מחרוזת.קלאס) .addStatement ("להחזיר את זה.שם") .build ()) .addMethod (MethodSpec .methodBuilder ("setName") .addParameter (String.class, "name") .addModifiers (Modifier.PUBLIC) .returns (String.class). addStatement ("this.name = name") .build ()) .addMethod (sumOfTen) .build ();

וככה נראה הקוד שנוצר:

אדם בכיתה ציבורית {פרטי שם מחרוזת; מחרוזת ציבורית getName () {להחזיר this.name; } ציבורי מחרוזת setName (שם מחרוזת) {this.name = שם; } ריק סטטי ציבורי sumOfTen (int מספר, מחרוזות רשימה) {int sum = 0; עבור (int i = 0; i <= 10; i ++) {sum + = i; }}}

7.2. יצירת ממשק

כדי ליצור ממשק Java, אנו משתמשים ב- interfaceBuilder () שיטת ה- TypeSpec.

אנו יכולים גם להגדיר שיטת ברירת מחדל על ידי ציון בְּרִירַת מֶחדָל ערך שינוי ב - addModifiers ():

TypeSpec person = TypeSpec .interfaceBuilder ("אדם") .addModifiers (Modifier.PUBLIC) .addField (defaultname) .addMethod (MethodSpec .methodBuilder ("getName") .addModifiers (Modifier.PUBLIC, Modifier.ABSTRACT) .build ()) .addMethod (MethodSpec .methodBuilder ("getDefaultName") .addModifiers (Modifier.PUBLIC, Modifier.DEFAULT) .addCode (CodeBlock .builder () .addStatement ("return DEFAULT_NAME") .build ()) .build ()) .build. ();

זה ייצור את קוד Java הבא:

ממשק ציבורי אדם {פרטית סטטית סופית מחרוזת DEFAULT_NAME = "אליס"; בטל getName (); בטל ברירת מחדל בטלה getDefaultName () {להחזיר DEFAULT_NAME; }}

7.3. יצירת אנום

כדי ליצור סוג מונה, נוכל להשתמש ב- enumBuilder () שיטת ה- TypeSpec. כדי לציין כל ערך שנמנה, נוכל לקרוא ל addEnumConstant () שיטה:

מין TypeSpec = TypeSpec .enumBuilder ("מין") .addModifiers (Modifier.PUBLIC) .addEnumConstant ("MALE") .addEnumConstant ("FEMALE") .addEnumConstant ("UNSPECIFIED") .build ();

התפוקה של האמור לעיל enumBuilder () ההיגיון הוא:

מגדר ציבורי ציבורי {MALE, FEMALE, UNSPECIFIED}

7.4. יצירת מעמד פנימי אנונימי

כדי ליצור מעמד פנימי אנונימי, אנו יכולים להשתמש ב- anonymousClassBuilder () שיטת ה- TypeSpec מעמד. ציין זאת עלינו לציין את מחלקת ההורים ב- addSuperinterface () שיטה. אחרת, הוא ישתמש בכיתת האב המוגדרת כברירת מחדל, כלומר לְהִתְנַגֵד:

TypeSpec השווה = TypeSpec .anonymousClassBuilder ("") .addSuperinterface (ParameterizedTypeName.get (Comparator.class, String.class)) .addMethod (MethodSpec .methodBuilder ("השווה") .addModifiers (Modifier.PUBLIC) .addParamasseter (Starr. , "a") .addParameter (String.class, "b") .returns (int.class) .addStatement ("return a.length () - b.length ()") .build ()) .build () ;

זה ייצור את קוד Java הבא:

Comparator חדש () {public int השווה (String a, String b) {return a.length () - b.length (); }});

8. מפרט ביאור

כדי להוסיף הערה לקוד שנוצר, אנו יכולים להתקשר ל- addAnnotation () שיטה בא MethodSpec אוֹ FieldSpec כיתת בנאים:

MethodSpec sumOfTen = MethodSpec .methodBuilder ("sumOfTen") .addAnnotation (Override.class) .addParameter (int.class, "number") .addParameter (strings) .addModifiers (Modifier.PUBLIC, Modifier.STATIC) .addCenI (sump) .לִבנוֹת();

מה שמייצר:

@Override public static void sumOfTen (int מספר, מחרוזות רשימה) {int sum = 0; עבור (int i = 0; i <= 10; i ++) {sum + = i; }}

במקרה שנצטרך לציין את ערך החבר, אנו יכולים להתקשר ל תוסיף חבר() שיטת ה- הערה ספציפי מעמד:

AnnotationSpec toString = AnnotationSpec. Builder (ToString.class) .addMember ("exclude", "\" name \ "") .build ();

פעולה זו תיצור את ההערה הבאה:

@ TooString (exclude = "name")

9. יצירת ג'אדוקים

ניתן ליצור Javadoc באמצעות קוד בלוק, או על ידי ציון הערך ישירות:

MethodSpec sumOfTen = MethodSpec .methodBuilder ("sumOfTen") .addJavadoc (CodeBlock .builder () .add ("סכום כל המספרים השלמים 0 עד 10") .build ()) .addAnnotation (Override.class) .addParameter (int. class, "number") .addParameter (strings) .addModifiers (Modifier.PUBLIC, Modifier.STATIC) .addCode (sumOfTenImpl) .build ();

זה ייצור את קוד Java הבא:

/ ** * סכום כל המספרים השלמים בין 0 ל -10 * / @ עקוף ריק סטטי ציבורי ריק sumOfTen (int מספר, מחרוזות רשימה) {int sum = 0; עבור (int i = 0; i <= 10; i ++) {sum + = i; }}

10. עיצוב

בואו נבדוק מחדש את הדוגמה של ה- FieldSpec אתחול בסעיף 5 המכיל תו מילוט המשמש לברוח מה"אליס " חוּט ערך:

אתחול ("\" אליס \ "")

ישנה דוגמא דומה גם בסעיף 8 כאשר אנו מגדירים את החבר שנכלל בהערה:

addMember ("אל תכלול", "\" שם \ "")

זה הופך להיות מסורבל כאשר קוד JavaPoet שלנו גדל ויש לו הרבה דומים חוּט לברוח או חוּט הצהרות שרשור.

תכונת עיצוב המחרוזת ב- JavaPoet עושה חוּט עיצוב ב beginControlFlow (), addStatement () אוֹ אתחול () שיטות קלות יותר. התחביר דומה ל- String.format () פונקציונליות בג'אווה. זה יכול לעזור לעצב מילוליות, מחרוזות, סוגים ושמות.

10.1. עיצוב מילולי

JavaPoet מחליף $ ל עם ערך מילולי בפלט. אנו יכולים לציין כל סוג פרימיטיבי ו חוּט ערכים בטיעונים:

שיטה פרטית MethodSpec createSumMethod (שם מחרוזת, int מ, int ל, מחרוזת) {return MethodSpec .methodBuilder (name) .returns (int.class) .addStatement ("int sum = 0") .beginControlFlow ("for (int i = $ L; i <= $ L; i ++) ", מ- to) .addStatement (" sum = sum $ L i ", operator). EndControlFlow () .addStatement (" sum return ") .build (); }

במקרה שנקרא createSumMethod () עם הערכים הבאים שצוינו:

createSumMethod ("sumOfOneHundred", 0, 100, "+");

JavaPoet יפיק את הפלט הבא:

int sumOfOneHundred () {int sum = 0; עבור (int i = 0; i <= 100; i ++) {sum = sum + i; } סכום החזר; }

10.2. חוּט עיצוב

חוּט עיצוב מייצר ערך עם המירכוש, שמתייחס אך ורק ל חוּט הקלד Java. JavaPoet מחליף $ S עם חוּט ערך בפלט:

פרטי סטטי MethodSpec createStringSupplier (String methodName, String fieldName) {return MethodSpec .methodBuilder (methodName). returns (String.class) .addStatement ("return $ S", fieldName) .build (); }

במקרה שנקרא createGetter () שיטה וספק ערכים אלה:

createStringSupplier ("getDefaultName", "Bob");

נקבל את קוד Java הבא שנוצר:

מחרוזת getDefaultName () {להחזיר "בוב"; }

10.3. הקלד עיצוב

JavaPoet מחליף $ T עם סוג בקוד Java שנוצר. JavaPoet מטפל בסוג בהצהרת הייבוא ​​באופן אוטומטי. אם היינו מספקים את הסוג כמילולי במקום זאת, JavaPoet לא היה מטפל בייבוא.

MethodSpec getCurrentDateMethod = MethodSpec .methodBuilder ("getCurrentDate"). חוזר (Date.class) .addStatement ("החזר $ T חדש ()", Date.class) .build ();

JavaPoet יפיק את הפלט הבא:

תאריך getCurrentDate () {החזר תאריך חדש (); }

10.4. עיצוב שם

למקרה שנצטרך להתייחס לשם של משתנה / פרמטר, שדה או שיטה, נוכל להשתמש בהם $ N ב- JavaPoet חוּט מעצב.

אנחנו יכולים להוסיף את הקודם getCurrentDateMethod () לשיטת ההפניה החדשה:

MethodSpec dateToString = MethodSpec .methodBuilder ("getCurrentDateAsString"). חוזר (String.class) .addStatement ("$ T מעצב = $ $ חדש ($ S)", DateFormat.class, SimpleDateFormat.class, "MM / dd / yyyy HH : mm: ss ") .addStatement (" return formatter.format ($ N ()) ", getCurrentDateMethod) .build ();

מה שמייצר:

מחרוזת getCurrentDateAsString () {פורמט DateFormat = חדש SimpleDateFormat ("MM / dd / yyyy HH: mm: ss"); return formatter.format (getCurrentDate ()); }

11. יצירת ביטויים למבדה

אנו יכולים להשתמש בתכונות שכבר בדקנו כדי ליצור ביטוי למבדה. לדוגמה, בלוק קוד שמדפיס את ה- שֵׁם שדה או משתנה מספר פעמים:

CodeBlock printNameMultipleTimes = CodeBlock .builder () .addStatement ("$ T names = new $ T ()", List.class, String.class, ArrayList.class) .addStatement ("$ T.range ($ L, $ L) .forEach (i -> names.add (name)) ", IntStream.class, 0, 10) .addStatement (" names.forEach (System.out :: println) ") .build ();

ההיגיון הזה מייצר את הפלט הבא:

שמות רשימות = ArrayList חדש (); IntStream.range (0, 10) .forEach (i -> names.add (name)); names.forEach (System.out :: println);

12. הפקת התפוקה באמצעות JavaFile

ה JavaFile class עוזר לתצורה ולהפקת פלט של הקוד שנוצר. כדי ליצור קוד Java, אנו פשוט בונים את ה- JavaFile, ספק את שם החבילה ומופע של TypeSpec לְהִתְנַגֵד.

12.1. כניסת קוד

כברירת מחדל, JavaPoet משתמש בשני רווחים לצורך כניסה. כדי לשמור על העקביות, כל הדוגמאות במדריך זה הוצגו עם הזחה של 4 רווחים, המוגדרת באמצעות לְשַׁנֵן() שיטה:

JavaFile javaFile = JavaFile .builder ("com.baeldung.javapoet.person", person) .indent ("") .build ();

12.2. יבוא סטטי

במקרה שנצטרך להוסיף ייבוא ​​סטטי, אנו יכולים להגדיר את הסוג ואת שם השיטה הספציפית ב- JavaFile על ידי קריאה ל addStaticImport () שיטה:

JavaFile javaFile = JavaFile .builder ("com.baeldung.javapoet.person", אדם) .indent ("") .addStaticImport (Date.class, "UTC") .addStaticImport (ClassName.get ("java.time", " ZonedDateTime ")," * ") .build ();

מה שמייצר את הצהרות הייבוא ​​הסטטיות הבאות:

ייבא java.util.Date.UTC סטטי; ייבא java.time.ZonedDateTime סטטי. *;

12.3. תְפוּקָה

ה לכתוב ל() השיטה מספקת פונקציונליות לכתיבת הקוד למספר יעדים, כגון זרם פלט רגיל (System.out) ו קוֹבֶץ.

כדי לכתוב קוד ג'אווה לזרם פלט רגיל, אנו פשוט קוראים לכתוב ל() שיטה, ולספק את System.out כטענה:

JavaFile javaFile = JavaFile .builder ("com.baeldung.javapoet.person", אדם) .indent ("") .addStaticImport (Date.class, "UTC") .addStaticImport (ClassName.get ("java.time", " ZonedDateTime ")," * ") .build (); javaFile.writeTo (System.out);

ה לכתוב ל() גם השיטה מקבלת java.nio.file. נתיב ו java.io. קובץ. אנו יכולים לספק את המקביל נָתִיב אוֹ קוֹבֶץ אובייקט על מנת ליצור את קובץ קוד המקור של Java לתיקיית היעד / נתיב היעד:

נתיב נתיב = Paths.get (destinationPath); javaFile.writeTo (נתיב);

למידע מפורט יותר בנושא JavaFileאנא עיין ב- Javadoc.

13. מסקנה

מאמר זה היווה מבוא לפונקציות JavaPoet, כמו יצירת שיטות, שדות, פרמטרים, סוגים, הערות ו- Javadocs.

JavaPoet מיועד לייצור קוד בלבד. במקרה שנרצה לבצע תכנות מתכנת עם Java, JavaPoet החל מגרסה 1.10.0 אינו תומך בהרכבת קוד ובהפעלתו.

כמו תמיד, הדוגמאות וקטעי הקוד זמינים ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found