in util-reflect/src/main/scala/com/twitter/util/reflect/Annotations.scala [111:164]
def findAnnotations(
clazz: Class[_],
parameterTypes: Seq[Class[_]] = Seq.empty
): scala.collection.Map[String, Array[Annotation]] = {
val clazzAnnotations = scala.collection.mutable.HashMap[String, Array[Annotation]]()
val constructorCount = clazz.getConstructors.length
val constructor = if (constructorCount > 1) {
if (parameterTypes.isEmpty)
throw new IllegalArgumentException(
"Multiple constructors detected and no parameter types specified.")
Try(clazz.getConstructor(parameterTypes: _*)) match {
case Return(con) => con
case Throw(t: NoSuchMethodException) =>
// translate from the reflection exception to a runtime exception
throw new IllegalArgumentException(t)
case Throw(t) => throw t
}
} else clazz.getConstructors.head
val fields: Array[Parameter] = constructor.getParameters
val clazzConstructorAnnotations: Array[Array[Annotation]] = constructor.getParameterAnnotations
var i = 0
while (i < fields.length) {
val field = fields(i)
val fieldAnnotations = clazzConstructorAnnotations(i)
if (fieldAnnotations.nonEmpty) clazzAnnotations.put(field.getName, fieldAnnotations)
i += 1
}
val declaredFields: Array[Field] = clazz.getDeclaredFields
var j = 0
while (j < declaredFields.length) {
val field = declaredFields(j)
if (field.getDeclaredAnnotations.nonEmpty) {
if (!clazzAnnotations.contains(field.getName)) {
clazzAnnotations.put(field.getName, field.getDeclaredAnnotations)
} else {
val existing = clazzAnnotations(field.getName)
// prefer field annotations over constructor annotation
mergeAnnotationArrays(field.getDeclaredAnnotations, existing)
}
}
j += 1
}
// find inherited annotations for declared fields
findDeclaredAnnotations(
clazz,
declaredFields.map(_.getName).toSet,
clazzAnnotations
)
}