撕开Class类的神秘面纱:一场来自网络安全老炮的深度解剖!

admin 2025年6月2日01:22:13评论16 views字数 21666阅读72分13秒阅读模式

听说你想搞懂Class类?别再啃那些干巴巴的文档了!作为在网络安全圈摸爬滚打多年的老兵,我来给你扒一扒这玩意儿的底裤,保证让你看完直呼“卧槽,原来是这么回事!”

public final class Class<T> implements java.io.Serializable,                                 GenericDeclaration,                                 Type,                                 AnnotatedElement 

Class这玩意儿,有点意思:

  • Class类?class关键字?哥们儿,这俩可不是一回事!前者是类,后者是关键字,别混淆了!

  • 构造函数?不存在的!只有个私有的,想自己new一个?JVM第一个不答应!

    JVM老大哥说了,Class类对象是它在ClassLoader加载时一手操办的,通过defineClass方法,就像捏泥人一样给你捏出来。

// 闲人免进!私有构造函数,禁止外部瞎搞! private Class(ClassLoader loader) {     // 初始化classLoader,防止JIT优化时瞎搞,以为它是null。     classLoader = loader; } 
  • Java里,每个类都藏着一个对应的Class对象,就像身份证一样。你写了个新类,编译后就会生成一个.class文件,这里面就装着这个Class对象。

  • 一个class关键字定义的类,内存里只有一个Class对象,实例对象和它之间是多对一的关系。简单说,Class对象就是类的“元数据”,告诉你这个类是什么,能干什么。

  • Class类的实例,说白了,就是运行时给你提供或获取对象类型信息的。

Class文件:JVM的“黑话”?

JVM只认class文件,这是铁律!不管你用啥语言,最终都得变成这玩意儿,才能让JVM“临幸”。

一个class文件,对应着一个类或接口的Class对象实例。但要注意,类或接口不一定非得有对应的磁盘文件,也能直接用类加载器生成。

JVM对class文件格式那叫一个严格!哪个字节代表啥,长度多少,顺序咋排,一点都不能乱!

3.1.1 格式?其实就是一堆二进制!

别被“格式”吓唬住,class文件就是一堆8位字节的二进制流,紧凑地排列在一起,没有任何分隔符。

如果数据项需要超过8位字节,那就按高位在前的方式分割存储。

class文件格式用的是类似C语言结构体的伪结构来存数据,只有两种数据类型:无符号数和表。

  • 无符号数:u1、u2、u4、u8,分别代表1个字节、2个字节、4个字节和8个字节的无符号数。用来描述数字、索引引用、数量值,或者UTF-8编码的字符串。

  • 表:多个无符号数或其他表组成,以_info结尾。用来描述有层次关系的复合结构数据。

说白了,整个class文件就是一张大表!

Class文件格式

从类加载看Class:它就是个“模版”!

类的执行流程:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载。(验证、准备、解析,统称“类的链接”)

撕开Class类的神秘面纱:一场来自网络安全老炮的深度解剖!

Class对象就是个“类模版”,用来生成多个实例对象。反射,其实就是在获取Class对象及其内部信息,然后反过来控制实例对象。就像黑客控制肉鸡一样,只不过这里控制的是对象。

反射?常用的那些“家伙”!

Java提供了Class类和java.lang.reflect类库来支持反射。反射包里,常用的类有:

  • java.lang.reflect.Method:代表类的方法。

  • java.lang.reflect.Field:代表类的成员变量。

  • java.lang.reflect.Constructor:代表类的构造器。

  • java.lang.Class:代表一个类。Class对象表示类加载后在堆中的对象,通过它能获取上面说的那些反射包里的东西。

创建Class类的三种“姿势”

  1. 运行时类.class:Class c=Student.class;

  2. 对象.getClass():Class c=new Student().getClass();

  3. Class.forName():Class<?> c = Class.forName("com.carl.test.classObject.TestClass");

Class类源码“解剖”:常用方法,一网打尽!

toString():我是谁?我在哪?

toString()把对象转成字符串,格式是:"class"或"interface"+空格+类的全限定名。如果是基本数据类型,就返回类型名;如果是void,就返回"void"。

public String toString() {     return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))             + getName(); } 

toGenericString():秀出我的“血统”!

toGenericString()返回描述类的字符串,包括修饰符和泛型参数。格式是:权限修饰符+类类型+全限定类名+泛型参数列表(没有就啥也不显示)。

public String toGenericString() {     if (isPrimitive()) {         return toString();     } else {         StringBuilder sb = new StringBuilder();          // Class modifiers are a superset of interface modifiers         int modifiers = getModifiers() & Modifier.classModifiers();         if (modifiers != 0) {             sb.append(Modifier.toString(modifiers));             sb.append(' ');         }          if (isAnnotation()) {             sb.append('@');         }         if (isInterface()) { // Note: all annotation types are interfaces             sb.append("interface");         } else {             if (isEnum())                 sb.append("enum");             else                 sb.append("class");         }         sb.append(' ');         sb.append(getName());          TypeVariable<?>[] typeparms = getTypeParameters();         if (typeparms.length > 0) {             boolean first = true;             sb.append('<');             for (TypeVariable<?> typeparm : typeparms) {                 if (!first)                     sb.append(',');                 sb.append(typeparm.getTypeName());                 first = false;             }             sb.append('>');         }          return sb.toString();     } } 

forName():召唤神龙!

forName(String className)返回与给定字符串名称的类或接口关联的Class对象。相当于forName(String name, boolean initialize,ClassLoader loader),其中loader是当前类的类加载器,className必须是类的全限定名。Class.forName("java.lang.Thread")会导致Thread类被初始化。

@CallerSensitive public static Class<?> forName(String className)         throws ClassNotFoundException {     //获取类加载器,来加载驱动     Class<?> caller = Reflection.getCallerClass();     //forName0方法参数说明:类的全路径名、加载后是否初始化该类、使用哪个类加载器、调用forName方法的类     return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }  private static native Class<?> forName0(String name, boolean initialize,                                             ClassLoader loader,                                             Class<?> caller)     throws ClassNotFoundException; 

forName(String name, boolean initialize,ClassLoader loader)用给定的类加载器返回与给定字符串名称的类或接口关联的Class对象。

参数说明:

name:类或接口的完全限定名。 initialize:是否初始化,true才初始化。 loader:指定的类加载器。

@CallerSensitive public static Class<?> forName(String name, boolean initialize,                                             ClassLoader loader)     throws ClassNotFoundException {     Class<?> caller = null;     SecurityManager sm = System.getSecurityManager();     if (sm != null) {         //如果安全管理器不为空,则调用getCallerClass方法进行反射调用,否则避免进行此调用产生的开销         caller = Reflection.getCallerClass();         if (sun.misc.VM.isSystemDomainLoader(loader)) {             ClassLoader ccl = ClassLoader.getClassLoader(caller);             if (!sun.misc.VM.isSystemDomainLoader(ccl)) {                 //如果类加载器不为空,则进行安全检查--获取当前类加载器进行权限校验,确保可以可以访问bootstraoClassLoader类加载器                 sm.checkPermission(                     SecurityConstants.GET_CLASSLOADER_PERMISSION);             }         }     }     return forName0(name, initialize, loader, caller); } 

newInstance():我要“变形”!

newInstance()创建Class对象表示的类的新实例。相当于空参构造器的new实例(String str = new String())。

@CallerSensitive public T newInstance()     throws InstantiationException, IllegalAccessException {     if (System.getSecurityManager() != null) {         //如果安全管理器不为空,则检查成员访问权限         checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);     }      // NOTE: the following code may not be strictly correct under     // the current Java memory model.      // 构造函数查找     if (cachedConstructor == null) {         //如果该类是Class类,则抛出异常,因为Class类本身就没有空参构造器         if (this == Class.class) {             throw new IllegalAccessException(                 "Can not call newInstance() on the Class for java.lang.Class"             );         }         try {             //构造函数的参数值,如果是空,则表示空参构造             Class<?>[] empty = {};             //调用getConstructor0方法,Member.DECLARED表示当前类或接口已声明的方法集合             //这里是抛出NoSuchMethodException的位置,如果找不到空参构造则会抛出异常             final Constructor<T> c = getConstructor0(empty, Member.DECLARED);             //不支持访问构造函数检查,必须在这里进行安全检查             java.security.AccessController.doPrivileged(                 new java.security.PrivilegedAction<Void>() {                     public Void run() {                         //检查当前构造函数是否可访问后,设置访问标志                         //true为可访问,不需要执行访问检查                         //false为不可访问,需要强制执行访问检查                         //这里是抛出SecurityException异常的位置                         c.setAccessible(true);                         return null;                     }                 });             cachedConstructor = c;         } catch (NoSuchMethodException e) {             //捕获NoSuchMethodException并抛出InstantiationException异常             throw (InstantiationException)                 new InstantiationException(getName()).initCause(e);         }     }     Constructor<T> tmpConstructor = cachedConstructor;     // 安全检查     //获取权限修饰符     //public=0x00000001 private=0x00000002 protected=0x00000004     int modifiers = tmpConstructor.getModifiers();     //快速检查成员访问权限     //检查当前实例化的类和构造函数是否为public权限,如果不是public,则进入,是public则跳过     if (!Reflection.quickCheckMemberAccess(this, modifiers)) {         //获取当前类的反射调用         Class<?> caller = Reflection.getCallerClass();         //如果当前创建的实例和反射调用的类不一样         if (newInstanceCallerCache != caller) {             //就会去检查反射调用的类的空参构造函数的访问权限是否是public             //这里是抛出IllegalAccessException的位置,确认不可访问,则会抛出异常             Reflection.ensureMemberAccess(caller, this, null, modifiers);             newInstanceCallerCache = caller;         }     }     // Run constructor     try {         //一系列检查后,调用构造器的创建实例方法         return tmpConstructor.newInstance((Object[])null);     } catch (InvocationTargetException e) {         //创建失败则会抛出异常         Unsafe.getUnsafe().throwException(e.getTargetException());         // Not reached         return null;     } } 

isAnnotation():我是注解吗?

isAnnotation()判断Class对象是不是注解类型。

public boolean isAnnotation() {     return (getModifiers() & ANNOTATION) != 0; } 

isSynthetic():我是“人造”的吗?

isSynthetic()判断Class是不是合成类。

public boolean isSynthetic() {     return (getModifiers() & SYNTHETIC) != 0; } 

getName():我的“大名”!

getName()返回Class对象表示的实体(类、接口、数组、基本类型或void)的名称。

  • 引用类型,非数组:返回类的二进制名称(全限定名)。

    java System.out.println(String.class.getName()); //输出结果为: java.lang.String

  • 基本数据类型或void:返回类型名。

    基本数据类型

    java System.out.println(short.class.getName()); //输出结果为: short

    void

    java System.out.println(void.class.getName()); //输出结果为: void

  • 数组类型:元素类型名称加上表示数组嵌套深度的'['字符。

    元素类型名称编码:

    元素类型
    编码
    boolean
    Z
    byte
    B
    char
    C
    class or Interface
    Lclassname
    double
    D
    float
    F
    int
    I
    long
    J
    short
    S

    class or interface的L表示元素类型名称,className表示全路径名。

    例子:

    • 基本数据类型的数组

      java long[][] test = new long[5][5]; System.out.println(test.getClass().getName()); //输出结果为: [[J //[[表示二维数组,J表示long类型的数组

      java int[][] testInt = new int[5][5]; System.out.println(testInt.getClass().getName()); //输出结果为: [[I //[[表示二维数组,I表示int类型的数组

      java byte[] testByte = new byte[5]; System.out.println(testByte.getClass().getName()); //输出结果为: [B //[表示一维数组,B表示byte类型的数组

    • 引用类型的数组

      java String[] testString = new String[5]; System.out.println(testString.getClass().getName()); //输出结果为: [Ljava.lang.String; //[表示一维数组,L表示引用数据类型的数组

      java Object[][] testObject = new Object[5][5]; System.out.println(testObject.getClass().getName()); //输出结果为: [[Ljava.lang.Object; //[[表示二维数组,L表示引用数据类型的数组

public String getName() {     String name = this.name;     if (name == null)         this.name = name = getName0();     return name; }  // 缓存该名称,减少对虚拟机的调用次数 private transient String name; private native String getName0(); 

getClassLoader():谁“罩着”我?

getClassLoader()返回当前类的类加载器。

  • 如果类由bootstrapClassLoader加载,返回null。

  • 如果存在安全管理器,会进行权限检查。

  • 如果对象表示基本数据类型或void,返回null。

@CallerSensitive public ClassLoader getClassLoader() {     ClassLoader cl = getClassLoader0();     if (cl == null)         return null;     SecurityManager sm = System.getSecurityManager();     if (sm != null) {         ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());     }     return cl; }  // Package-private to allow ClassLoader access ClassLoader getClassLoader0() { return classLoader; }  // 在JVM中初始化,而不是在私有构造函数中初始化 // 该字段从反射接入中过滤,即getDeclaredField()方法,将会抛出NoSuchFieldException异常 private final ClassLoader classLoader; 

getTypeParameters():我的“基因”!

getTypeParameters()返回TypeVariable对象的数组,表示泛型声明的类型变量。

public TypeVariable<Class<T>>[] getTypeParameters() {     ClassRepository info = getGenericInfo();     if (info != null)         return (TypeVariable<Class<T>>[])info.getTypeParameters();     else         return (TypeVariable<Class<T>>[])new TypeVariable<?>[0]; } 
TypeVariable<Class<ArrayList>>[] typeParameters = ArrayList.class.getTypeParameters(); System.out.println(typeParameters[0]); //输出结果为: E 

getGenericSuperclass():我的“老子”是谁?

getGenericSuperclass()返回Type对象,表示Class对象表示的实体的直接父类。

public native Class<? super T> getSuperclass(); public Type getGenericSuperclass() {     ClassRepository info = getGenericInfo();     if (info == null) {         return getSuperclass();     }      // Historical irregularity:     // Generic signature marks interfaces with superclass = Object     // but this API returns null for interfaces     if (isInterface()) {         return null;     }      return info.getSuperclass(); } 
Type genericSuperclass = String.class.getGenericSuperclass(); System.out.println(genericSuperclass); //输出结果为: class java.lang.Object 

getInterface():我的“盟友”!

getInterface()返回Class对象表示的类或接口实现的接口,不携带泛型参数。

Object[][] testObject = new Object[5][5]; Type[] genericInterfaces1 = testObject.getClass().getGenericInterfaces(); for (Type type : genericInterfaces1){     System.out.println(type); } //输出结果为: interface java.lang.Cloneable interface java.io.Serializable 
public Class<?>[] getInterfaces() {     ReflectionData<T> rd = reflectionData();     if (rd == null) {         // no cloning required         return getInterfaces0();     } else {         Class<?>[] interfaces = rd.interfaces;         if (interfaces == null) {             interfaces = getInterfaces0();             rd.interfaces = interfaces;         }         // defensively copy before handing over to user code         return interfaces.clone();     } }  // Lazily create and cache ReflectionData private ReflectionData<T> reflectionData() {     SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;     int classRedefinedCount = this.classRedefinedCount;     ReflectionData<T> rd;     if (useCaches &&         reflectionData != null &&         (rd = reflectionData.get()) != null &&         rd.redefinedCount == classRedefinedCount) {         return rd;     }     // else no SoftReference or cleared SoftReference or stale ReflectionData     // -> create and replace new instance     return newReflectionData(reflectionData, classRedefinedCount); }  private native Class<?>[] getInterfaces0(); 

getGenericInterfaces():我的“高级盟友”!

getGenericInterfaces()返回类或接口的直接实现接口数组,携带泛型参数。

public Type[] getGenericInterfaces() {     ClassRepository info = getGenericInfo();     return (info == null) ?  getInterfaces() : info.getSuperInterfaces(); } 

getPackage():我在哪个“地盘”混?

getPackage()获取类的包名、规范和版本。

public Package getPackage() {     return Package.getPackage(this); } 
Package aPackage = String.class.getPackage(); System.out.println(aPackage); //输出结果为: package java.lang, Java Platform API Specification, version 1.8 

getEnclosingMethod():谁把我“包养”了?

getEnclosingMethod()如果Class对象表示方法中的局部类或匿名类,返回Method对象,表示底层类的直接封闭方法。

@CallerSensitive public Method getEnclosingMethod() throws SecurityException {     EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();      if (enclosingInfo == null)         return null;     else {         if (!enclosingInfo.isMethod())             return null;          MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),                                                                                                     getFactory());         Class<?>  returnType        = toClass(typeInfo.getReturnType());         Type []   parameterTypes  = typeInfo.getParameterTypes();         Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];          // Convert Types to Classes; returned types *should*         // be class objects since the methodDescriptor's used         // don't have generics information         for(int i = 0; i < parameterClasses.length; i++)             parameterClasses[i] = toClass(parameterTypes[i]);          // Perform access check         Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();         enclosingCandidate.checkMemberAccess(Member.DECLARED,                                                                                                         Reflection.getCallerClass(), true);         /*          * Loop over all declared methods; match method name,          * number of and type of parameters, *and* return          * type.  Matching return type is also necessary          * because of covariant returns, etc.          */         for(Method m: enclosingCandidate.getDeclaredMethods()) {             if (m.getName().equals(enclosingInfo.getName()) ) {                 Class<?>[] candidateParamClasses = m.getParameterTypes();                 if (candidateParamClasses.length == parameterClasses.length) {                     boolean matches = true;                     for(int i = 0; i < candidateParamClasses.length; i++) {                         if (!candidateParamClasses[i].equals(parameterClasses[i])) {                             matches = false;                             break;                         }                     }                      if (matches) { // finally, check return type                         if (m.getReturnType().equals(returnType) )                             return m;                     }                 }             }         }          throw new InternalError("Enclosing method not found");     } }  private native Object[] getEnclosingMethod0();  private EnclosingMethodInfo getEnclosingMethodInfo() {     Object[] enclosingInfo = getEnclosingMethod0();     if (enclosingInfo == null)         return null;     else {         return new EnclosingMethodInfo(enclosingInfo);     } }  private static Class<?> toClass(Type o) {  if (o instanceof GenericArrayType)   return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),                                                      0)                         .getClass();  return (Class<?>)o; } 

getEnclosingConstructor():谁把我“生”出来的?

getEnclosingConstructor()如果Class对象表示构造函数中的本地类或匿名类,返回Constructor对象,表示底层类的直接括号中的构造函数。

@CallerSensitive public Constructor<?> getEnclosingConstructor() throws SecurityException {     EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();      if (enclosingInfo == null)         return null;     else {         if (!enclosingInfo.isConstructor())             return null;          ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),                                                                                                                                      getFactory());         Type []   parameterTypes  = typeInfo.getParameterTypes();         Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];          // Convert Types to Classes; returned types *should*         // be class objects since the methodDescriptor's used         // don't have generics information         for(int i = 0; i < parameterClasses.length; i++)             parameterClasses[i] = toClass(parameterTypes[i]);          // Perform access check         Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();         enclosingCandidate.checkMemberAccess(Member.DECLARED,                                                                                                         Reflection.getCallerClass(), true);         /*          * Loop over all declared constructors; match number          * of and type of parameters.          */         for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {             Class<?>[] candidateParamClasses = c.getParameterTypes();             if (candidateParamClasses.length == parameterClasses.length) {                 boolean matches = true;                 for(int i = 0; i < candidateParamClasses.length; i++) {                     if (!candidateParamClasses[i].equals(parameterClasses[i])) {                         matches = false;                         break;                     }                 }                  if (matches)                     return c;             }         }          throw new InternalError("Enclosing constructor not found");     } } 

getDeclaringClass():我从哪里来?

getDeclaringClass()如果Class对象表示的类或接口是另一个类的成员,返回声明它的类的Class对象。

@CallerSensitive public Class<?> getDeclaringClass() throws SecurityException {     final Class<?> candidate = getDeclaringClass0();      if (candidate != null)         candidate.checkPackageAccess(                         ClassLoader.getClassLoader(Reflection.getCallerClass()), true);     return candidate; }  private native Class<?> getDeclaringClass0(); 

getEnclosingClass():我的“保护伞”是谁?

getEnclosingClass()返回内部类的直接外部类,如果是顶层类,返回null。

@CallerSensitive public Class<?> getEnclosingClass() throws SecurityException {     // There are five kinds of classes (or interfaces):     // a) Top level classes     // b) Nested classes (static member classes)     // c) Inner classes (non-static member classes)     // d) Local classes (named classes declared within a method)     // e) Anonymous classes      // JVM Spec 4.8.6: A class must have an EnclosingMethod     // attribute if and only if it is a local class or an     // anonymous class.     EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();     Class<?> enclosingCandidate;      if (enclosingInfo == null) {         // This is a top level or a nested class or an inner class (a, b, or c)         enclosingCandidate = getDeclaringClass();     } else {         Class<?> enclosingClass = enclosingInfo.getEnclosingClass();         // This is a local class or an anonymous class (d or e)         if (enclosingClass == this || enclosingClass == null)             throw new InternalError("Malformed enclosing method information");         else             enclosingCandidate = enclosingClass;     }      if (enclosingCandidate != null)         enclosingCandidate.checkPackageAccess(                         ClassLoader.getClassLoader(Reflection.getCallerClass()), true);     return enclosingCandidate; } 

getSimpleName():我的“小名”!

getSimpleName()返回Class对象的类名,匿名类返回空字符串,数组返回附加了'[]'的组件类型名称。

public String getSimpleName() {     if (isArray())         return getComponentType().getSimpleName()+"[]";      String simpleName = getSimpleBinaryName();     if (simpleName == null) { // top level class         simpleName = getName();         return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name     }     // According to JLS3 "Binary Compatibility" (13.1) the binary     // 非包类的名称是直接包含类的二进制名称,后跟'$'     // (对于嵌套类或内部类): 类名.     // (对于本地类): 1或多个数字后跟类名     // (对于匿名类): 1或多个数字.      // 由于getSimpleBinaryName()将去掉立即包含的类的二进制名称,因此我们看到的时一个正则表达式     //"[0-9]"后跟类名的字符串,匿名类的类名为空字符串      //从类名中删除前缀"[0-9]"     int length = simpleName.length();     if (length < 1 || simpleName.charAt(0) != '$')         throw new InternalError("Malformed class name");     int index = 1;     while (index < length && isAsciiDigit(simpleName.charAt(index)))         index++;     // Eventually, this is the empty string iff this is an anonymous class     return simpleName.substring(index); } 

getTypeName():我的“身份证号”!

getTypeName()返回类的全限定名,基本类型或void返回对应字符串,数组返回全限定名加[]或基本类型加[]

public String getTypeName() {     if (isArray()) {         try {             Class<?> cl = this;             int dimensions = 0;             while (cl.isArray()) {                 dimensions++;                 cl = cl.getComponentType();             }             StringBuilder sb = new StringBuilder();             sb.append(cl.getName());             for (int i = 0; i < dimensions; i++) {                 sb.append("[]");             }             return sb.toString();         } catch (Throwable e) {/*FALLTHRU*/}     }     return getName(); } 

getCanonicalName():我的“官方认证名”!

getCanonicalName()返回Java语言规范定义的类的规范名称,本地类、匿名类或组件类型没有规范名的数组返回null。

public String getCanonicalName() {     if (isArray()) {         String canonicalName = getComponentType().getCanonicalName();         if (canonicalName != null)             return canonicalName + "[]";         else             return null;     }     if (isLocalOrAnonymousClass())         return null;     Class<?> enclosingClass = getEnclosingClass();     if (enclosingClass == null) { // top level class         return getName();     } else {         String enclosingName = enclosingClass.getCanonicalName();         if (enclosingName == null)             return null;         return enclosingName + "." + getSimpleName();     } } 

isAnonymousClass():我是“无名氏”吗?

isAnonymousClass()判断是否为匿名类。

public boolean isAnonymousClass() {     return "".equals(getSimpleName()); } 

isLocalClass():我是“本地户口”吗?

isLocalClass()判断是否是本地类。

public boolean isLocalClass() {     return isLocalOrAnonymousClass() && !isAnonymousClass(); } 

isMemberClass():我是“正式员工”吗?

isMemberClass()判断是否为成员类。

public boolean isMemberClass() {     return getSimpleBinaryName() != null && !isLocalOrAnonymousClass(); } 

getClasses():我的“朋友圈”!

getClasses()返回Class对象的类的所有公共类和成员接口。

@CallerSensitive public Class<?>[] getClasses() {     checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);      // Privileged so this implementation can look at DECLARED classes,     // something the caller might not have privilege to do.  The code here     // is allowed to look at DECLARED classes because (1) it does not hand     // out anything other than public members and (2) public member access     // has already been ok'd by the SecurityManager.      return java.security.AccessController.doPrivileged(         new java.security.PrivilegedAction<Class<?>[]>() {             public Class<?>[] run() {                 List<Class<?>> list = new ArrayList<>();                 Class<?> currentClass = Class.this;                 while (currentClass != null) {                     Class<?>[] members = currentClass.getDeclaredClasses();                     for (int i = 0; i < members.length; i++) {                         if (Modifier.isPublic(members[i].getModifiers())) {                             list.add(members[i]);                         }                     }                     currentClass = currentClass.getSuperclass();                 }                 return list.toArray(new Class<?>[0]);             }         }); } 

getFields():我的“公开属性”!

getFields()返回类的所有可访问(public)公共字段Field对象的数组。

@CallerSensitive public Field[] getFields() throws SecurityException {     checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);     return copyFields(privateGetPublicFields(null)); } 

getMethods():我的“公开技能”!

getMethods()返回类对象对应类或接口中的所有public方法,包括声明的和继承的。

@CallerSensitive public Method[] getMethods() throws SecurityException {     checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);     return copyMethods(privateGetPublicMethods()); } 
//测试类的父类 public class SuperClass {      public static void play(){         System.out.println("static play()");     } } 

```java //测试类 public class MemberClass {     private String name;

private String sex;  public String description;  public int age;  public static void sl

黑客/

原文始发于微信公众号(龙哥网络安全):撕开Class类的神秘面纱:一场来自“网络安全老炮”的深度解剖!

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月2日01:22:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   撕开Class类的神秘面纱:一场来自网络安全老炮的深度解剖!https://cn-sec.com/archives/4122558.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息