Lors de l'exécution du traitement des annotations dans l'EDI, les informations d'annotation définies par @Retention (RetentionPolicy.SOURCE)
peuvent ne pas être obtenues dans certaines conditions.
OS
Windows 10
Java
openjdk 10.0.2
Eclipse
Photon (4.8.0)
※Pleiades
IntelliJ
IntelliJ IDEA 2018.2.3 (Community Edition)
Gradle
Gradle 4.10
Structure du projet
|-foo/
| `-src/main/java/
| `-sample/foo/
| |-Fizz.java
| `-Buzz.java
|
|-bar/
| |-src/main/java/
| | `-sample/bar/
| | |-MyRuntimeRetention.java
| | |-MyClassRetention.java
| | |-MySourceRetention.java
| | `-MyProcessor.java
| |
| `-src/main/resources/
| `-META-INF/services
| `-javax.annotation.processing.Processor
|
|-build.gradle
`-settings.gradle
--Multi-projet de foo
, bar
--Un projet dans lequel bar
implémente le traitement des annotations
--foo
est un projet qui utilise le traitement d'annotation de bar
--MyRuntimeRetention.java
, MyClassRetention.java
, MySourceRetention.java
sont leurs propres annotations et Retention
est défini sur la valeur correspondant au nom.
MyRuntimeRetention.java
package sample.bar;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRuntimeRetention {
}
MyClassRetention.java
package sample.bar;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MyClassRetention {
}
MySourceRetention.java
package sample.bar;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface MySourceRetention {
}
--Une classe dans laquelle MyProcessor.java
implémente le traitement des annotations
MyProcessor.java
package sample.bar;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic.Kind;
public class MyProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Elements elements = this.processingEnv.getElementUtils();
if (!annotations.isEmpty()) {
this.printAnnotations(elements.getTypeElement("sample.foo.Fizz"));
this.printAnnotations(elements.getTypeElement("sample.foo.Buzz"));
}
return true;
}
private void printAnnotations(TypeElement element) {
element.getAnnotationMirrors().forEach(annotation -> {
this.processingEnv.getMessager().printMessage(Kind.NOTE, element.getSimpleName() + " : " + annotation);
});
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.RELEASE_10;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return Set.of(MySourceRetention.class.getCanonicalName());
}
}
TypeElement
de Fizz
, de la classe Buzz
et sortie d'une liste d'annotations définies dans la classeFizz.java
package sample.foo;
import sample.bar.MyClassRetention;
import sample.bar.MyRuntimeRetention;
import sample.bar.MySourceRetention;
@MyRuntimeRetention
@MyClassRetention
@MySourceRetention
public class Fizz {
}
Buzz.java
package sample.foo;
import sample.bar.MyClassRetention;
import sample.bar.MyRuntimeRetention;
import sample.bar.MySourceRetention;
@MyRuntimeRetention
@MyClassRetention
@MySourceRetention
public class Buzz {
}
Fizz
, Buzz
du projet foo
a trois annotations faites soi-même définies dans la classe.Dans cet état, modifiez uniquement la classe ** Fizz
et exécutez ** la compilation.
Ensuite, le résultat sera différent lors de l'exécution dans Gradle et lors de l'exécution dans l'IDE (Eclipse, IntelliJ).
> gradle :foo:compileJava
Mise en garde:Fizz : @sample.bar.MyRuntimeRetention
Mise en garde:Fizz : @sample.bar.MyClassRetention
Mise en garde:Fizz : @sample.bar.MySourceRetention
Mise en garde:Buzz : @sample.bar.MyRuntimeRetention
Mise en garde:Buzz : @sample.bar.MyClassRetention
Mise en garde:Buzz : @sample.bar.MySourceRetention
@ MySourceRetention
n'a pas pu obtenir l'annotation de la classe Buzz
.@ MySourceRetention
ne peut pas être obtenu à partir des informations d'annotation de la classe Buzz
.--Modifiez non seulement la classe Fizz
mais aussi la classe Buzz
, puis exécutez la construction pour faire fonctionner le processus d'annotation.
Eclipse
@ MySourceRetention
dans Buzz
.IntelliJ
@ MySourceRetention
.--Lorsque Retention
est défini sur SOURCE
, Les informations d'annotation ne restent pas dans le fichier de classe /RetentionPolicy.html#SOURCE)
--Lorsque le traitement des annotations fonctionne dans IDE (Eclipse, IntelliJ), il semble que vous ne puissiez pas obtenir les informations de l'annotation dont Retention
est SOURCE
, qui est définie dans la classe sans modification.
Recommended Posts