Java Academy · บทเรียน

ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์

เขียน AbstractProcessor เพื่อสร้างไฟล์ซอร์สหรือตรวจสอบโค้ดขณะคอมไพล์

บทเรียน 4 จาก 413 ขั้นตอน

ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์ เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

ตัวประมวลผลแอนโนเทชันคืออะไร

ตัวประมวลผลแอนโนเทชัน (APT — เครื่องมือประมวลผลแอนโนเทชัน) ทำงานระหว่างการคอมไพล์ โดยตรวจสอบแอนโนเทชันในซอร์สโค้ด และสามารถสร้างไฟล์ซอร์สใหม่ ไฟล์ทรัพยากร หรือแจ้งข้อผิดพลาดและคำเตือนของคอมไพเลอร์ได้

AbstractProcessor: คลาสพื้นฐาน

ขยาย javax.annotation.processing.AbstractProcessor และเขียนทับ process() เพื่อจัดการองค์ประกอบที่มีแอนโนเทชัน พร้อมประกาศแอนโนเทชันที่รองรับและเวอร์ชันซอร์สของ Java

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;

@SupportedAnnotationTypes("com.example.GenerateBuilder")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
public class BuilderProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getElementsAnnotatedWith(GenerateBuilder.class)) {
            generateBuilder((TypeElement) e);
        }
        return true;
    }
    private void generateBuilder(TypeElement cls) { /* generate source */ }
}

การลงทะเบียนตัวประมวลผล

ลงทะเบียนตัวประมวลผลใน META-INF/services/javax.annotation.processing.Processor โดยระบุชื่อคลาสแบบเต็ม เครื่องมือสร้างโปรเจกต์ (Maven, Gradle) จะค้นพบตัวประมวลผลโดยอัตโนมัติ

# META-INF/services/javax.annotation.processing.Processor
com.example.BuilderProcessor

การสร้างไฟล์ซอร์ส

ใช้ processingEnv.getFiler().createSourceFile() เพื่อเขียนไฟล์ .java ใหม่ จากนั้นคอมไพเลอร์จะคอมไพล์ไฟล์ที่สร้างขึ้นในรอบเดียวกันหรือรอบถัดไป

JavaFileObject file = processingEnv.getFiler()
    .createSourceFile("com.example.UserBuilder");
try (Writer w = file.openWriter()) {
    w.write("package com.example;\n");
    w.write("public class UserBuilder {\n");
    w.write("  // generated builder\n");
    w.write("}\n");
}

การตรวจสอบโมเดลองค์ประกอบ

ตัวประมวลผลแอนโนเทชันทำงานกับ Element (ไม่ใช่ Class เพราะซอร์สยังไม่ได้ถูกคอมไพล์) ให้ใช้ TypeElement, VariableElement และ ExecutableElement

TypeElement classElement = (TypeElement) element;
String className = classElement.getSimpleName().toString();
List<VariableElement> fields = classElement.getEnclosedElements().stream()
    .filter(e -> e.getKind() == ElementKind.FIELD)
    .map(e -> (VariableElement) e)
    .collect(Collectors.toList());

การส่งข้อผิดพลาดของคอมไพเลอร์

เรียกใช้ processingEnv.getMessager().printMessage() เพื่อส่งข้อผิดพลาด คำเตือน หรือหมายเหตุ นี่คือวิธีที่แอนโนเทชันข้อจำกัดแบบกำหนดเองใช้แจ้งการละเมิดขณะคอมไพล์

processingEnv.getMessager().printMessage(
    Diagnostic.Kind.ERROR,
    "@GenerateBuilder requires at least one field",
    element
);

การประมวลผลหลายรอบ

การประมวลผลแอนโนเทชันเกิดขึ้นเป็นรอบ ๆ หากคุณสร้างไฟล์ที่มีแอนโนเทชัน ตัวประมวลผลอาจทำงานอีกครั้งในรอบถัดไป roundEnv.processingOver() ใช้ระบุรอบสุดท้าย

if (roundEnv.processingOver()) {
    // last round — write summary files or do cleanup
}

เบื้องหลังการทำงานของ Lombok

Lombok ใช้ส่วนขยาย APT ที่ไม่เป็นมาตรฐานเพื่อแก้ไข AST ของคลาสที่มีอยู่ (ซึ่งข้อกำหนดไม่อนุญาต) แอนโนเทชันอย่าง @Data, @Builder และ @Getter จะสร้างเมธอดลงในคลาสที่คอมไพล์แล้วโดยตรง

การสร้างโค้ดด้วย MapStruct

MapStruct สร้างการใช้งานตัวแมปที่ปลอดภัยด้านชนิดขณะคอมไพล์ โดยอ่านอินเทอร์เฟซที่มี @Mapper และเขียนการใช้งานออกมาเป็นคลาส Java ปกติ จึงไม่ต้องใช้รีเฟล็กชันขณะรันไทม์

@Mapper
public interface UserMapper {
    UserDto toDto(User user);
    User toEntity(UserDto dto);
}
// MapStruct generates: UserMapperImpl.java at compile time

การทดสอบตัวประมวลผลแอนโนเทชัน

ใช้ google/compile-testing หรือ Kapt (สำหรับ Kotlin) เพื่อทดสอบตัวประมวลผลแบบยูนิต โดยป้อนสตริงซอร์สแล้วตรวจสอบไฟล์ที่สร้างขึ้นหรือข้อผิดพลาดของคอมไพเลอร์

JavaFileObject src = JavaFileObjects.forSourceString("Test",
    "@GenerateBuilder public class Test { private String name; }");
Compilation c = Compiler.javac().withProcessors(new BuilderProcessor()).compile(src);
CompilationSubject.assertThat(c).succeeded();
CompilationSubject.assertThat(c).generatedSourceFile("TestBuilder");

การจัดแพ็กเกจตัวประมวลผล

จัดแพ็กเกจตัวประมวลผลไว้ในโมดูล Maven แยกต่างหาก โมดูลแอนโนเทชัน (มีเฉพาะแอนโนเทชัน) เป็นการพึ่งพาแบบ compile ส่วนโมดูลตัวประมวลผลใช้ขอบเขต annotationProcessor และไม่ควรเป็นการพึ่งพาขณะรันไทม์

// build.gradle:
dependencies {
    implementation "com.example:my-annotations:1.0"
    annotationProcessor "com.example:my-processor:1.0"
}

ตรวจสอบความเข้าใจ

ควรลงทะเบียนตัวประมวลผลแอนโนเทชันไว้ที่ใดเพื่อให้ค้นพบโดยอัตโนมัติ

สรุปทบทวน

ขยาย AbstractProcessor ลงทะเบียนใน META-INF/services สร้างซอร์สด้วย Filer และส่งข้อผิดพลาดด้วย Messager จัดแพ็กเกจตัวประมวลผลแยกต่างหาก ใช้ compile-testing สำหรับการทดสอบแบบยูนิต ซึ่งช่วยขจัดค่าใช้จ่ายของรีเฟล็กชันขณะรันไทม์

เริ่มต้นได้ฟรี

เรียนรู้ Java ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
104
บทเรียน
374

คำถามที่พบบ่อย

บทเรียน “ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์”

เขียน AbstractProcessor เพื่อสร้างไฟล์ซอร์สหรือตรวจสอบโค้ดขณะคอมไพล์ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การกำหนดคำอธิบายประกอบ: องค์ประกอบและค่าเริ่มต้น
  2. นโยบายการคงอยู่และชนิดเป้าหมาย
  3. การประมวลผลคำอธิบายประกอบขณะทำงาน
  4. ตัวประมวลผลคำอธิบายประกอบขณะคอมไพล์
← กลับไปที่ Java Academy