In AOP development we often use Element’s getAnnotation(Class var1) method to get the attributes passed in for custom annotations

Such as:

@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class TTEventType(val value: KClass<*>)
Copy the code

When we get KClass < * > type occurs javax.mail. Lang. Model. The MirroredTypeException, this is because

The annotation returned by this method could contain an element whose value is of type Class. This value cannot be returned directly: information necessary to locate and load a class (such as the class loader to use) is not available, and the class might not be loadable at all. Attempting to read a Class object by invoking the relevant method on the returned annotation will result in a MirroredTypeException, from which the corresponding TypeMirror may be extracted. Similarly, attempting to read a Class[]-valued element will result in a MirroredTypesException.

Dealing with a

If you forced magic out of getAnnotation(), you could use MirroredTypeException

public class MirroredTypeException
extends MirroredTypesException

Thrown when an application attempts to access the Class object corresponding to a TypeMirror.
Copy the code

Get TypeMirror from exception capture

    inline fun <reified T : Annotation> Element.getAnnotationClassValue(f: T.() -> KClass<*>) =
        try {
            getAnnotation(T::class.java).f()
            throw Exception("Expected to get a MirroredTypeException")
        } catch (e: MirroredTypeException) {
            e.typeMirror
        }
Copy the code

Handle two

Let’s start with AnnotationMirror in List
getAnnotationMirrors() method:


private fun getEventTypeAnnotationMirror(typeElement: VariableElement, clazz: Class<*>): AnnotationMirror? {
        val clazzName = clazz.name
        for (m in typeElement.annotationMirrors) {
            if (m.annotationType.toString() == clazzName) {
                return m
            }
        }
        return null
    }

    private fun getAnnotationValue(annotationMirror: AnnotationMirror, key: String): AnnotationValue? {
        for ((key1, value) in annotationMirror.elementValues) {
            if(key1!! .simpleName.toString() == key) {return value
            }
        }
        returnnull } private fun getMyValue(foo: VariableElement, clazz: Class<*>, key: String): TypeMirror? { val am = getEventTypeAnnotationMirror(foo, clazz) ? :return null
        val av = getAnnotationValue(am, key)
        return if (av == null) {
            null
        } else {
            av.value as TypeMirror
        }

    }

Copy the code
  val typeMirror = getMyValue(variableElement,TTEventType::class.java,"value")
  
    messager.printMessage(Diagnostic.Kind.NOTE, " --typeMirror-- $typeMirror")
Copy the code

reference

Getting Class values from Annotations in an AnnotationProcessor