目录
AnnotationMetadataReadingVisitor
五种类型的Class
Class类种注释解释有五种类型的Class
用一个demo进行说明:
/**
a) Top level classes 顶层类
*/
public class TopLevelClass {
/**
* c) Inner classes (non-static member classes) 非静态的成员类
*/
class InnerClass {
}
/**
* b) Nested classes (static member classes) 静态的成员类
*/
static class NestedClass {
}
public static void main(String[] args) {
/**
* d) Local classes (named classes declared within a method) 局部类 申明在方法种的类
*/
class LocalClass {
}
// e) Anonymous classes 匿名类
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("TopLevelClass的外围类是: " + (TopLevelClass.class.getEnclosingClass() == null ? null : TopLevelClass.class.getEnclosingClass().getSimpleName()));
System.out.println("InnerClass的外围类是: " + InnerClass.class.getEnclosingClass().getSimpleName());
System.out.println("NestedClass的外围类是: " + NestedClass.class.getEnclosingClass().getSimpleName());
System.out.println("LocalClass的外围类是: " + LocalClass.class.getEnclosingClass().getSimpleName());
System.out.println("AnonymousClass的外围类是: " + runnable.getClass().getEnclosingClass().getSimpleName());
//memberClasses 包括Nested classes 和 Inner classes
System.out.println("TopLevelClass声明的类有: " + Arrays.stream(TopLevelClass.class.getDeclaredClasses()).map(Class::getSimpleName).collect(Collectors.toList()));
System.out.println("NestedClass声明的类有: " + Arrays.stream( NestedClass.class.getDeclaredClasses()).map(Class::getSimpleName).collect(Collectors.toList()));
System.out.println("声明TopLevelClass的类是: " + (TopLevelClass.class.getDeclaringClass() == null ? null : TopLevelClass.class.getDeclaringClass().getSimpleName()));
System.out.println("声明NestedClass的类是" + NestedClass.class.getDeclaringClass().getSimpleName());
}
}
运行结果:
ClassMedata
ClassMedata可以对一个隐含的类的对象进行封装,提供获取这个对象的类信息的一系列方法。
在Spring对注解的增强中我们看到一个类StandardAnnotationMetadata。它实现了ClassMetadata。在Spring注解模型中被广泛用到。
看下这个接口的实现。
public class StandardClassMetadata implements ClassMetadata {
/**
* ClassMetadata可以对一个隐含的类进行管理, 提供对这个类的信息的获取机制
* introspected : 内省
*/
private final Class<?> introspectedClass;
/**
* Create a new StandardClassMetadata wrapper for the given Class.
* @param introspectedClass the Class to introspect
*/
public StandardClassMetadata(Class<?> introspectedClass) {
Assert.notNull(introspectedClass, "Class must not be null");
this.introspectedClass = introspectedClass;
}
/**
* 获取这个隐含的类
*/
public final Class<?> getIntrospectedClass() {
return this.introspectedClass;
}
/**
* 获取类的名称
*/
@Override
public String getClassName() {
return this.introspectedClass.getName();
}
/**
* 是否是一个接口
*/
@Override
public boolean isInterface() {
return this.introspectedClass.isInterface();
}
/**
* 是否是一个注解
*/
@Override
public boolean isAnnotation() {
return this.introspectedClass.isAnnotation();
}
/**
* 是否是一个抽象类, 通过修饰符获取
*/
@Override
public boolean isAbstract() {
return Modifier.isAbstract(this.introspectedClass.getModifiers());
}
/**
* 是否是一个具体的类(非接口, 非抽象类)
*/
@Override
public boolean isConcrete() {
return !(isInterface() || isAbstract());
}
/**
* 是不是final类,通过修饰符获取
*/
@Override
public boolean isFinal() {
return Modifier.isFinal(this.introspectedClass.getModifiers());
}
/**
* 是否是独立的类, (Top level classes 或者 Nested classes)
* !hasEnclosingClass() 没有外围类 =》Top level classes
* this.introspectedClass.getDeclaringClass() != null && Modifier.isStatic(this.introspectedClass.getModifiers() 被其他类申明, 且不是静态的 =》 Nested classes
*/
@Override
public boolean isIndependent() {
return (!hasEnclosingClass() ||
(this.introspectedClass.getDeclaringClass() != null &&
Modifier.isStatic(this.introspectedClass.getModifiers())));
}
/**
* 是否有外围类
*/
@Override
public boolean hasEnclosingClass() {
return (this.introspectedClass.getEnclosingClass() != null);
}
/**
* 获取其外围类
*/
@Override
@Nullable
public String getEnclosingClassName() {
Class<?> enclosingClass = this.introspectedClass.getEnclosingClass();
return (enclosingClass != null ? enclosingClass.getName() : null);
}
/**
* 是否有超类
*/
@Override
public boolean hasSuperClass() {
return (this.introspectedClass.getSuperclass() != null);
}
/**
* 获取超类名称
*/
@Override
@Nullable
public String getSuperClassName() {
Class<?> superClass = this.introspectedClass.getSuperclass();
return (superClass != null ? superClass.getName() : null);
}
/**
* 获取接口名称
*/
@Override
public String[] getInterfaceNames() {
Class<?>[] ifcs = this.introspectedClass.getInterfaces();
String[] ifcNames = new String[ifcs.length];
for (int i = 0; i < ifcs.length; i++) {
ifcNames[i] = ifcs[i].getName();
}
return ifcNames;
}
/**
* 获取所有成员类的名称
*/
@Override
public String[] getMemberClassNames() {
LinkedHashSet<String> memberClassNames = new LinkedHashSet<>(4);
for (Class<?> nestedClass : this.introspectedClass.getDeclaredClasses()) {
memberClassNames.add(nestedClass.getName());
}
return StringUtils.toStringArray(memberClassNames);
}
AnnotationMetadataReadingVisitor
StandardClassMetadata下面除了StandardAnnotationMetadata的实现,还有一个AnnotationMetadataReadingVisitor。
StandardAnnotationMetadata继承了StandardClassMetadata。他们对Class类型信息的获取用到是放射技术。性能较低,因此Spring也提供了AnnotationMetadataReadingVisitor,是通过对字节码的读取技术(ClassReader)获取类信息。
但是二者能做到的事情是一样。如果想了解这个AnnotationMetadataReadingVisitor,可以了解一下字节码