Bạn có thể xây dựng một bộ xử lý Chú cho điều đó. Bộ xử lý chú thích là các plugin trình biên dịch có thể chạy lúc biên dịch. Lỗi của chúng xuất hiện dưới dạng lỗi trình biên dịch và thậm chí có thể tạm dừng bản dựng.
Dưới đây là một số mẫu mã (Tôi không chạy nó mặc dù):
@SupportedAnnotationTypes("*") // needed to run on all classes being compiled
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class DefaultConstructor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (TypeElement type : ElementFilter.typesIn(roundEnv.getRootElements())) {
if (requiresDefaultConstructor(type))
checkForDefaultConstructor(type);
}
return false;
}
private void checkForDefaultConstructor(TypeElement type) {
for (ExecutableElement cons :
ElementFilter.constructorsIn(type.getEnclosedElements())) {
if (cons.getParameters().isEmpty())
return;
}
// Couldn't find any default constructor here
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR, "type is missing a default constructor",
type);
}
private boolean requiresDefaultConstructor(TypeElement type) {
// sample: require any JPA Entity to have a default constructor
return type.getAnnotation(Entity.class)) != null
|| type.getQualifiedName().toString().contains("POJO");
}
}
Bộ xử lý chú thích trở nên dễ dàng hơn nếu bạn giới thiệu một chú thích (ví dụ RequiresDefaultAnnotation).
Tuyên bố yêu cầu của việc có một vòng loại mặc định
:: Tôi cũng giả định rằng OP yêu cầu cho một cơ chế có thể ngăn chặn các lỗi ngẫu nhiên cho các nhà phát triển, đặc biệt là được viết bởi một người khác. ::
Phải có một cơ chế để khai báo lớp nào yêu cầu một bộ xử lý mặc định. Hy vọng rằng, bạn đã có một tiêu chuẩn cho điều đó, cho dù đó là một mẫu trong tên, mẫu trong vòng loại, một chú thích có thể, và/hoặc một kiểu cơ sở. Trong mẫu tôi đã cung cấp ở trên, bạn có thể chỉ định tiêu chí trong phương thức requiresDefaultConstructor()
. Dưới đây là ví dụ về cách có thể thực hiện:
Dựa trên mẫu tên. TypeElement
cung cấp quyền truy cập vào tên gói và tên đầy đủ.
return type.getQualifiedName().toString().contains("POJO");
Dựa trên chú thích có trong khai báo kiểu. Ví dụ: tất cả các lớp Java Bean Entity phải có các hàm tạo không mặc định
return type.getAnnotation(Entity.class) != null;
Dựa trên lớp trừu tượng hoặc giao diện.
TypeElement basetype = processingEnv.getElements().getTypeElement("com.notnoop.mybase");
return processingEnv.getTypes().isSubtype(type.asType(), basetype.asType());
[Đề xuất cách tiếp cận]: Nếu bạn đang sử dụng giao diện basetype, tôi khuyên bạn nên pha trộn các cách tiếp cận chú thích với giao diện kiểu cơ sở. Bạn có thể khai báo chú thích, ví dụ: MyPlain
, cùng với chú giải meta: @Inherited
. Sau đó, bạn có thể chú thích loại cơ sở với chú thích đó, sau đó tất cả các lớp con sẽ kế thừa chú thích. Sau đó, phương pháp của bạn sẽ chỉ được
return type.getAnnotation(MyPlain.class) != null;
Điều này là tốt bởi vì đó là một chút cấu hình hơn, nếu mô hình thực sự là dựa trên loại hệ thống cấp bậc, và bạn sở hữu lớp gốc.
Như đã đề cập trước đó, chỉ vì nó được gọi là "xử lý chú thích", điều đó có nghĩa là bạn phải sử dụng chú thích! Cách tiếp cận nào trong danh sách bạn muốn theo dõi phụ thuộc vào ngữ cảnh của bạn. Về cơ bản, điểm là bất kỳ logic nào bạn muốn cấu hình trong các công cụ thực thi triển khai của mình, logic đó sẽ đi vào requiresDefaultConstructor
.
Lớp học bộ vi xử lý sẽ chạy trên
xử lý Chú gọi trên bất kỳ lớp học nhất định phụ thuộc vào SupportedAnnotationTypes
. Nếu chú thích meta SupportedAnnotationTypes
chỉ định chú thích cụ thể, thì bộ xử lý sẽ chỉ chạy trên các lớp chứa chú thích đó.
Nếu SupportedAnnotationTypes
là "*"
thì trình xử lý sẽ được gọi trên tất cả các lớp, được chú thích hay không! Kiểm tra các [Javadoc] (http://java.sun.com/javase/6/docs/api/javax/annotation/processing/Processor.html#getSupportedAnnotationTypes()), trong đó nêu:
Cuối cùng, "*"
tự đại diện cho bộ của tất cả các loại chú thích, bao gồm tập rỗng Lưu ý rằng một bộ xử lý không nên tuyên bố "*"
trừ khi nó được. thực sự xử lý tất cả các file; tuyên bố chú thích không cần thiết có thể gây ra một sự suy giảm hiệu suất trong một số môi trường
Xin lưu ý cách.được trả lại để đảm bảo rằng bộ xử lý không yêu cầu tất cả chú thích.
Thậm chí tồi tệ hơn là "hacky" và chậm là nó sẽ không gây ra một lỗi biên dịch! – tster
Đáng buồn thay trong Java không có cách nào để phát hành một lỗi trình biên dịch cho các trường hợp như vậy khi bạn đang tải các lớp học nằm ngoài tầm kiểm soát của bạn. – Alfonso