移除不必要的泛型约束

This commit is contained in:
huangchengxing 2022-07-05 16:20:49 +08:00
parent 254e6f5315
commit c343b51e38
8 changed files with 59 additions and 64 deletions

View File

@ -12,27 +12,25 @@ import java.util.Comparator;
* 构建时需要传入比较器获取属性值时将根据比较器对合成注解进行排序 * 构建时需要传入比较器获取属性值时将根据比较器对合成注解进行排序
* 然后选择具有所需属性的排序最靠前的注解用于获取属性值 * 然后选择具有所需属性的排序最靠前的注解用于获取属性值
* *
* @param <A> 合成注解类型
* @author huangchengxing * @author huangchengxing
*/ */
public class CacheableSynthesizedAnnotationAttributeProcessor<A extends SynthesizedAnnotation<?>> implements public class CacheableSynthesizedAnnotationAttributeProcessor implements SynthesizedAnnotationAttributeProcessor {
SynthesizedAnnotationAttributeProcessor<A> {
private final Table<String, Class<?>, Object> valueCaches = new RowKeyTable<>(); private final Table<String, Class<?>, Object> valueCaches = new RowKeyTable<>();
private final Comparator<A> annotationComparator; private final Comparator<SynthesizedAnnotation> annotationComparator;
/** /**
* 创建一个带缓存的注解值选择器 * 创建一个带缓存的注解值选择器
* *
* @param annotationComparator 注解比较器排序更靠前的注解将被优先用于获取值 * @param annotationComparator 注解比较器排序更靠前的注解将被优先用于获取值
*/ */
public CacheableSynthesizedAnnotationAttributeProcessor(Comparator<A> annotationComparator) { public CacheableSynthesizedAnnotationAttributeProcessor(Comparator<SynthesizedAnnotation> annotationComparator) {
this.annotationComparator = annotationComparator; this.annotationComparator = annotationComparator;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T> T getAttributeValue(String attributeName, Class<T> attributeType, Collection<A> synthesizedAnnotations) { public <T> T getAttributeValue(String attributeName, Class<T> attributeType, Collection<? extends SynthesizedAnnotation> synthesizedAnnotations) {
Object value = valueCaches.get(attributeName, attributeType); Object value = valueCaches.get(attributeName, attributeType);
// 此处理论上不可能出现缓存值为nul的情况 // 此处理论上不可能出现缓存值为nul的情况
if (ObjectUtil.isNotNull(value)) { if (ObjectUtil.isNotNull(value)) {

View File

@ -7,14 +7,14 @@ import java.lang.annotation.Annotation;
* *
* @author huangchengxing * @author huangchengxing
*/ */
public interface SynthesizedAnnotation<T> extends Annotation { public interface SynthesizedAnnotation extends Annotation {
/** /**
* 获取该合成注解对应的根节点 * 获取该合成注解对应的根节点
* *
* @return 数据源 * @return 数据源
*/ */
T getRoot(); Object getRoot();
/** /**
* 该合成注解是为根对象 * 该合成注解是为根对象

View File

@ -8,7 +8,7 @@ import java.util.Collection;
* @author huangchengxing * @author huangchengxing
*/ */
@FunctionalInterface @FunctionalInterface
public interface SynthesizedAnnotationAttributeProcessor<A extends SynthesizedAnnotation<?>> { public interface SynthesizedAnnotationAttributeProcessor {
/** /**
* 从一批被合成注解中获取指定名称与类型的属性值 * 从一批被合成注解中获取指定名称与类型的属性值
@ -16,9 +16,9 @@ public interface SynthesizedAnnotationAttributeProcessor<A extends SynthesizedAn
* @param attributeName 属性名称 * @param attributeName 属性名称
* @param attributeType 属性类型 * @param attributeType 属性类型
* @param synthesizedAnnotations 被合成的注解 * @param synthesizedAnnotations 被合成的注解
* @param <T> 属性类型 * @param <R> 属性类型
* @return 属性值 * @return 属性值
*/ */
<T> T getAttributeValue(String attributeName, Class<T> attributeType, Collection<A> synthesizedAnnotations); <R> R getAttributeValue(String attributeName, Class<R> attributeType, Collection<? extends SynthesizedAnnotation> synthesizedAnnotations);
} }

View File

@ -36,14 +36,14 @@ public interface SynthesizedAnnotationSelector {
* @param newAnnotation 新获取的注解该参数不允许为空 * @param newAnnotation 新获取的注解该参数不允许为空
* @return 被合成的注解 * @return 被合成的注解
*/ */
<T, A extends SynthesizedAnnotation<T>> A choose(A oldAnnotation, A newAnnotation); <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation);
/** /**
* 返回距离根对象更近的注解当距离一样时优先返回旧注解 * 返回距离根对象更近的注解当距离一样时优先返回旧注解
*/ */
class NearestAndOldestPrioritySelector implements SynthesizedAnnotationSelector { class NearestAndOldestPrioritySelector implements SynthesizedAnnotationSelector {
@Override @Override
public <T, A extends SynthesizedAnnotation<T>> A choose(A oldAnnotation, A newAnnotation) { public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() < oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation; return newAnnotation.getVerticalDistance() < oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
} }
} }
@ -53,7 +53,7 @@ public interface SynthesizedAnnotationSelector {
*/ */
class NearestAndNewestPrioritySelector implements SynthesizedAnnotationSelector { class NearestAndNewestPrioritySelector implements SynthesizedAnnotationSelector {
@Override @Override
public <T, A extends SynthesizedAnnotation<T>> A choose(A oldAnnotation, A newAnnotation) { public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() <= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation; return newAnnotation.getVerticalDistance() <= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
} }
} }
@ -63,7 +63,7 @@ public interface SynthesizedAnnotationSelector {
*/ */
class FarthestAndOldestPrioritySelector implements SynthesizedAnnotationSelector { class FarthestAndOldestPrioritySelector implements SynthesizedAnnotationSelector {
@Override @Override
public <T, A extends SynthesizedAnnotation<T>> A choose(A oldAnnotation, A newAnnotation) { public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() > oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation; return newAnnotation.getVerticalDistance() > oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
} }
} }
@ -73,7 +73,7 @@ public interface SynthesizedAnnotationSelector {
*/ */
class FarthestAndNewestPrioritySelector implements SynthesizedAnnotationSelector { class FarthestAndNewestPrioritySelector implements SynthesizedAnnotationSelector {
@Override @Override
public <T, A extends SynthesizedAnnotation<T>> A choose(A oldAnnotation, A newAnnotation) { public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() >= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation; return newAnnotation.getVerticalDistance() >= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
} }
} }

View File

@ -6,10 +6,9 @@ import java.lang.reflect.AnnotatedElement;
/** /**
* 表示基于特定规则聚合的一组注解 * 表示基于特定规则聚合的一组注解
* *
* @param <A> 合成注解类型
* @author huangchengxing * @author huangchengxing
*/ */
public interface SyntheticAnnotation<A extends SynthesizedAnnotation<?>> extends Annotation, AnnotatedElement { public interface SyntheticAnnotation extends Annotation, AnnotatedElement {
/** /**
* 获取合成注解选择器 * 获取合成注解选择器
@ -23,16 +22,15 @@ public interface SyntheticAnnotation<A extends SynthesizedAnnotation<?>> extends
* *
* @return 合成注解属性处理器 * @return 合成注解属性处理器
*/ */
SynthesizedAnnotationAttributeProcessor<A> getAttributeProcessor(); SynthesizedAnnotationAttributeProcessor getAttributeProcessor();
/** /**
* 获取已合成的注解 * 获取已合成的注解
* *
* @param annotationType 注解类型 * @param annotationType 注解类型
* @param <T> 注解类型
* @return 已合成的注解 * @return 已合成的注解
*/ */
<T extends Annotation> SynthesizedAnnotation<T> getSynthesizedAnnotation(Class<T> annotationType); SynthesizedAnnotation getSynthesizedAnnotation(Class<?> annotationType);
/** /**
* 获取当前的注解类型 * 获取当前的注解类型
@ -96,8 +94,8 @@ public interface SyntheticAnnotation<A extends SynthesizedAnnotation<?>> extends
* @param <T> 注解类型 * @param <T> 注解类型
* @return 合成注解 * @return 合成注解
*/ */
static <T extends Annotation> SyntheticAnnotation<SyntheticMetaAnnotation.MetaAnnotation> of(T rootAnnotation) { static <T extends Annotation> SyntheticAnnotation of(T rootAnnotation) {
return new SyntheticMetaAnnotation<>(rootAnnotation); return new SyntheticMetaAnnotation(rootAnnotation);
} }
} }

View File

@ -20,16 +20,15 @@ import java.util.stream.Stream;
/** /**
* 合成注解代理类 * 合成注解代理类
* *
* @param <A> 代理的注解类型
* @author huangchengxing * @author huangchengxing
*/ */
class SyntheticAnnotationProxy<A extends Annotation> implements InvocationHandler { class SyntheticAnnotationProxy implements InvocationHandler {
private final SyntheticAnnotation<?> syntheticAnnotation; private final SyntheticAnnotation syntheticAnnotation;
private final SynthesizedAnnotation<A> annotation; private final SynthesizedAnnotation annotation;
private final Map<String, BiFunction<Method, Object[], Object>> methods; private final Map<String, BiFunction<Method, Object[], Object>> methods;
SyntheticAnnotationProxy(SyntheticAnnotation<?> syntheticAnnotation, SynthesizedAnnotation<A> annotation) { SyntheticAnnotationProxy(SyntheticAnnotation syntheticAnnotation, SynthesizedAnnotation annotation) {
this.syntheticAnnotation = syntheticAnnotation; this.syntheticAnnotation = syntheticAnnotation;
this.annotation = annotation; this.annotation = annotation;
this.methods = new HashMap<>(9); this.methods = new HashMap<>(9);
@ -45,18 +44,17 @@ class SyntheticAnnotationProxy<A extends Annotation> implements InvocationHandle
* *
* @param annotationType 注解类型 * @param annotationType 注解类型
* @param syntheticAnnotation 合成注解 * @param syntheticAnnotation 合成注解
* @param <A> 代理的注解类型
* @return 代理注解 * @return 代理注解
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static <A extends Annotation> A create( static <T extends Annotation> T create(
Class<A> annotationType, SyntheticAnnotation<?> syntheticAnnotation) { Class<T> annotationType, SyntheticAnnotation syntheticAnnotation) {
final SynthesizedAnnotation<A> annotation = syntheticAnnotation.getSynthesizedAnnotation(annotationType); final SynthesizedAnnotation annotation = syntheticAnnotation.getSynthesizedAnnotation(annotationType);
final SyntheticAnnotationProxy<A> proxyHandler = new SyntheticAnnotationProxy<>(syntheticAnnotation, annotation); final SyntheticAnnotationProxy proxyHandler = new SyntheticAnnotationProxy(syntheticAnnotation, annotation);
if (ObjectUtil.isNull(annotation)) { if (ObjectUtil.isNull(annotation)) {
return null; return null;
} }
return (A) Proxy.newProxyInstance( return (T) Proxy.newProxyInstance(
annotationType.getClassLoader(), annotationType.getClassLoader(),
new Class[]{annotationType, SyntheticProxyAnnotation.class}, new Class[]{annotationType, SyntheticProxyAnnotation.class},
proxyHandler proxyHandler
@ -122,21 +120,21 @@ class SyntheticAnnotationProxy<A extends Annotation> implements InvocationHandle
* *
* @author huangchengxing * @author huangchengxing
*/ */
interface SyntheticProxyAnnotation<A extends Annotation, T extends SynthesizedAnnotation<?>> extends SynthesizedAnnotation<A> { interface SyntheticProxyAnnotation extends SynthesizedAnnotation {
/** /**
* 获取该注解所属的合成注解 * 获取该注解所属的合成注解
* *
* @return 合成注解 * @return 合成注解
*/ */
SyntheticAnnotation<T> getSyntheticAnnotation(); SyntheticAnnotation getSyntheticAnnotation();
/** /**
* 获取该代理注解对应的已合成注解 * 获取该代理注解对应的已合成注解
* *
* @return 理注解对应的已合成注解 * @return 理注解对应的已合成注解
*/ */
SynthesizedAnnotation<A> getSynthesizedAnnotation(); SynthesizedAnnotation getSynthesizedAnnotation();
} }

View File

@ -43,17 +43,17 @@ import java.util.Map;
* @see AnnotationUtil * @see AnnotationUtil
* @see SynthesizedAnnotationSelector * @see SynthesizedAnnotationSelector
*/ */
public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticAnnotation<SyntheticMetaAnnotation.MetaAnnotation> { public class SyntheticMetaAnnotation implements SyntheticAnnotation {
/** /**
* 根注解即当前查找的注解 * 根注解即当前查找的注解
*/ */
private final A source; private final Annotation source;
/** /**
* 包含根注解以及其元注解在内的全部注解实例 * 包含根注解以及其元注解在内的全部注解实例
*/ */
private final Map<Class<? extends Annotation>, MetaAnnotation> metaAnnotationMap; private final Map<Class<? extends Annotation>, SynthesizedAnnotation> metaAnnotationMap;
/** /**
* 合成注解选择器 * 合成注解选择器
@ -63,7 +63,7 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
/** /**
* 合成注解属性处理器 * 合成注解属性处理器
*/ */
private final SynthesizedAnnotationAttributeProcessor<SyntheticMetaAnnotation.MetaAnnotation> attributeProcessor; private final SynthesizedAnnotationAttributeProcessor attributeProcessor;
/** /**
* 基于指定根注解为其层级结构中的全部注解构造一个合成注解 * 基于指定根注解为其层级结构中的全部注解构造一个合成注解
@ -72,12 +72,12 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
* *
* @param source 源注解 * @param source 源注解
*/ */
public SyntheticMetaAnnotation(A source) { public SyntheticMetaAnnotation(Annotation source) {
this( this(
source, SynthesizedAnnotationSelector.NEAREST_AND_OLDEST_PRIORITY, source, SynthesizedAnnotationSelector.NEAREST_AND_OLDEST_PRIORITY,
new CacheableSynthesizedAnnotationAttributeProcessor<>( new CacheableSynthesizedAnnotationAttributeProcessor(
Comparator.comparing(MetaAnnotation::getVerticalDistance) Comparator.comparing(SynthesizedAnnotation::getVerticalDistance)
.thenComparing(MetaAnnotation::getHorizontalDistance) .thenComparing(SynthesizedAnnotation::getHorizontalDistance)
) )
); );
} }
@ -89,9 +89,9 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
* @param annotationSelector 合成注解选择器 * @param annotationSelector 合成注解选择器
*/ */
public SyntheticMetaAnnotation( public SyntheticMetaAnnotation(
A annotation, Annotation annotation,
SynthesizedAnnotationSelector annotationSelector, SynthesizedAnnotationSelector annotationSelector,
SynthesizedAnnotationAttributeProcessor<SyntheticMetaAnnotation.MetaAnnotation> attributeProcessor) { SynthesizedAnnotationAttributeProcessor attributeProcessor) {
Assert.notNull(annotation, "annotation must not null"); Assert.notNull(annotation, "annotation must not null");
Assert.notNull(annotationSelector, "annotationSelector must not null"); Assert.notNull(annotationSelector, "annotationSelector must not null");
Assert.notNull(attributeProcessor, "attributeProcessor must not null"); Assert.notNull(attributeProcessor, "attributeProcessor must not null");
@ -108,7 +108,7 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
* *
* @return 根注解 * @return 根注解
*/ */
public A getSource() { public Annotation getSource() {
return source; return source;
} }
@ -117,7 +117,7 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
* *
* @return 已解析的元注解信息 * @return 已解析的元注解信息
*/ */
Map<Class<? extends Annotation>, MetaAnnotation> getMetaAnnotationMap() { Map<Class<? extends Annotation>, SynthesizedAnnotation> getMetaAnnotationMap() {
return metaAnnotationMap; return metaAnnotationMap;
} }
@ -137,8 +137,8 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
* @return 合成注解属性处理器 * @return 合成注解属性处理器
*/ */
@Override @Override
public SynthesizedAnnotationAttributeProcessor<MetaAnnotation> getAttributeProcessor() { public SynthesizedAnnotationAttributeProcessor getAttributeProcessor() {
return null; return this.attributeProcessor;
} }
/** /**
@ -149,8 +149,8 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T extends Annotation> SynthesizedAnnotation<T> getSynthesizedAnnotation(Class<T> annotationType) { public SynthesizedAnnotation getSynthesizedAnnotation(Class<?> annotationType) {
return (SynthesizedAnnotation<T>)metaAnnotationMap.get(annotationType); return metaAnnotationMap.get(annotationType);
} }
/** /**
@ -187,7 +187,7 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
public <T extends Annotation> T getAnnotation(Class<T> annotationType) { public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
return Opt.ofNullable(annotationType) return Opt.ofNullable(annotationType)
.map(metaAnnotationMap::get) .map(metaAnnotationMap::get)
.map(MetaAnnotation::getAnnotation) .map(SynthesizedAnnotation::getAnnotation)
.map(annotationType::cast) .map(annotationType::cast)
.orElse(null); .orElse(null);
} }
@ -244,8 +244,8 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
metaAnnotationMap.put(source.annotationType(), new MetaAnnotation(source, source, 0, 0)); metaAnnotationMap.put(source.annotationType(), new MetaAnnotation(source, source, 0, 0));
new MetaAnnotationScanner().scan( new MetaAnnotationScanner().scan(
(index, annotation) -> { (index, annotation) -> {
MetaAnnotation oldAnnotation = metaAnnotationMap.get(annotation.annotationType()); SynthesizedAnnotation oldAnnotation = metaAnnotationMap.get(annotation.annotationType());
MetaAnnotation newAnnotation = new MetaAnnotation(source, annotation, index, metaAnnotationMap.size()); SynthesizedAnnotation newAnnotation = new MetaAnnotation(source, annotation, index, metaAnnotationMap.size());
if (ObjectUtil.isNull(oldAnnotation)) { if (ObjectUtil.isNull(oldAnnotation)) {
metaAnnotationMap.put(annotation.annotationType(), newAnnotation); metaAnnotationMap.put(annotation.annotationType(), newAnnotation);
} else { } else {
@ -261,7 +261,7 @@ public class SyntheticMetaAnnotation<A extends Annotation> implements SyntheticA
* *
* @author huangchengxing * @author huangchengxing
*/ */
public static class MetaAnnotation implements Annotation, SynthesizedAnnotation<Annotation> { public static class MetaAnnotation implements Annotation, SynthesizedAnnotation {
private final Annotation root; private final Annotation root;
private final Annotation annotation; private final Annotation annotation;

View File

@ -3,8 +3,10 @@ package cn.hutool.core.annotation;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.lang.annotation.*; import java.lang.annotation.ElementType;
import java.util.Map; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** /**
* 合成注解{@link SyntheticMetaAnnotation}的测试用例 * 合成注解{@link SyntheticMetaAnnotation}的测试用例
@ -16,7 +18,7 @@ public class SyntheticMetaAnnotationTest {
@Test @Test
public void testSynthesisAnnotation() { public void testSynthesisAnnotation() {
ChildAnnotation rootAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class); ChildAnnotation rootAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
SyntheticMetaAnnotation<ChildAnnotation> syntheticMetaAnnotation = new SyntheticMetaAnnotation<>(rootAnnotation); SyntheticMetaAnnotation syntheticMetaAnnotation = new SyntheticMetaAnnotation(rootAnnotation);
Assert.assertEquals(syntheticMetaAnnotation.getSource(), rootAnnotation); Assert.assertEquals(syntheticMetaAnnotation.getSource(), rootAnnotation);
Assert.assertEquals(syntheticMetaAnnotation.annotationType(), SyntheticMetaAnnotation.class); Assert.assertEquals(syntheticMetaAnnotation.annotationType(), SyntheticMetaAnnotation.class);
Assert.assertEquals(1, syntheticMetaAnnotation.getDeclaredAnnotations().length); Assert.assertEquals(1, syntheticMetaAnnotation.getDeclaredAnnotations().length);
@ -28,28 +30,27 @@ public class SyntheticMetaAnnotationTest {
Assert.assertEquals("Child's Parent!", syntheticMetaAnnotation.getAttribute("parentValue", String.class)); Assert.assertEquals("Child's Parent!", syntheticMetaAnnotation.getAttribute("parentValue", String.class));
Assert.assertEquals("Child's GrandParent!", syntheticMetaAnnotation.getAttribute("grandParentValue", String.class)); Assert.assertEquals("Child's GrandParent!", syntheticMetaAnnotation.getAttribute("grandParentValue", String.class));
Map<Class<? extends Annotation>, SyntheticMetaAnnotation.MetaAnnotation> annotationMap = syntheticMetaAnnotation.getMetaAnnotationMap();
ChildAnnotation childAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ChildAnnotation.class); ChildAnnotation childAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ChildAnnotation.class);
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ChildAnnotation.class)); Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ChildAnnotation.class));
Assert.assertNotNull(childAnnotation); Assert.assertNotNull(childAnnotation);
Assert.assertEquals("Child!", childAnnotation.childValue()); Assert.assertEquals("Child!", childAnnotation.childValue());
Assert.assertEquals("Child!", childAnnotation.childValueAlias()); Assert.assertEquals("Child!", childAnnotation.childValueAlias());
Assert.assertEquals(childAnnotation.grandParentType(), Integer.class); Assert.assertEquals(childAnnotation.grandParentType(), Integer.class);
Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation<>(childAnnotation)); Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation(childAnnotation));
ParentAnnotation parentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ParentAnnotation.class); ParentAnnotation parentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ParentAnnotation.class);
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ParentAnnotation.class)); Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ParentAnnotation.class));
Assert.assertNotNull(parentAnnotation); Assert.assertNotNull(parentAnnotation);
Assert.assertEquals("Child's Parent!", parentAnnotation.parentValue()); Assert.assertEquals("Child's Parent!", parentAnnotation.parentValue());
Assert.assertEquals("java.lang.Void", parentAnnotation.grandParentType()); Assert.assertEquals("java.lang.Void", parentAnnotation.grandParentType());
Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation<>(parentAnnotation)); Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation(parentAnnotation));
GrandParentAnnotation grandParentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(GrandParentAnnotation.class); GrandParentAnnotation grandParentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(GrandParentAnnotation.class);
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(GrandParentAnnotation.class)); Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(GrandParentAnnotation.class));
Assert.assertNotNull(grandParentAnnotation); Assert.assertNotNull(grandParentAnnotation);
Assert.assertEquals("Child's GrandParent!", grandParentAnnotation.grandParentValue()); Assert.assertEquals("Child's GrandParent!", grandParentAnnotation.grandParentValue());
Assert.assertEquals(grandParentAnnotation.grandParentType(), Integer.class); Assert.assertEquals(grandParentAnnotation.grandParentType(), Integer.class);
Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation<>(grandParentAnnotation)); Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation(grandParentAnnotation));
} }
// 注解结构如下 // 注解结构如下