虛擬機類加載過程 &&java基礎包之 java.lang.Class源碼解析

在看Class的源碼之前我們先來看看虛擬機的類加載機制柏腻。
什么是類加載機制:
就是將Class文件存入內存,并對數(shù)據校驗系吭,轉換解析五嫂,初始化,最終形成能被虛擬機直接使用的模型 的過程
類加載 可以分為7個階段

1 加載

  • 加載過程中需要完成以下三件事:
    • 通過類的全限定名類獲取定義此類的二進制字節(jié)流
    • 將這個字節(jié)流所代表的靜態(tài)存儲結構轉換成方法區(qū)運行時數(shù)據結
    • 在內存中生成一個代表這個類的java.lang.Class對象肯尺,作為數(shù)據訪問的入口

2 驗證

  • 視為了確保Class文件的字節(jié)流中包含的信息符合當前虛擬機的要求沃缘,而且還不會危害虛擬機自身的安全。
  • 驗證階段很重要则吟,但也不是必要的槐臀,假如說一些代碼被反復使用并驗證過可靠性了,實施階段就可以嘗試用-Xverify:none參數(shù)來關閉大部分的類驗證措施氓仲,以簡短類加載時間水慨。

連接 (可以細化為4-6階段)

3 準備

準備階段是正式為類變量分配內存并且設置類變量【靜態(tài)變量】初始值的位置得糜。這個設置初始值不是直接將賦值設置進去,而是數(shù)據類型的零值 晰洒。 比如 有代碼public static int value=1 朝抖,但是實際上其實只是設置了value=0; 但是有一種情況是例外,就是用了final關鍵字的時候谍珊,就是被初始化為1治宣;

4 解析

5初始化

 - new,getstatic,putstatic,invokestatic關鍵字(new 對象,讀取/賦值靜態(tài)字段(final除外)砌滞,調用靜態(tài)方法)
 - 反射調用侮邀,如果之前類沒有被初始化,那么這時候會初始化
 - 初始化某個類 贝润,但是其父類還沒有被初始化的時候,父類也會初始化 (該類如果是一個接口則不會初始化父類)
 - 虛擬機啟動 绊茧,用戶指定執(zhí)行的類(如main方法調用的時候的那個類)
 - 動態(tài)語言支持 java.lang.invoke.MethodHandle返回RET_getstatic,RET_putstatic

6 使用

7 卸載

類加載器:
java中定義的類加載器可以細分為三種
1.啟動類加載器
2.擴展類加載器
3.應用程序加載器
一般都是三種加載器互相配合加載。加載關系基本符合雙親委派模型打掘。
什么是雙親委派模型:

雙親委派模型

工作過程:
比如我們要開始加載某個類了按傅,這時候它不會自己馬上就去加載,它會把這個請求委派給父類胧卤,然后不斷往上委派唯绍,直到頂層。當父類說:哎呀枝誊,我加載不了哦【搜索范圍找不到這個類】况芒,子類就只有自己去加載了。

雙親委派模型被破壞:
1.兼容1.0的時候的LoadClass
2.SPI的加載:線程上下文加載器 父類去請求子類的加載器

OSGi(Open Service Gateway Initiative叶撒,直譯為“開放服務網關”)實際上是一個由
OSGi 聯(lián)盟(OSGi Alliance绝骚,如圖 1-1 所示)發(fā)起的以 Java 為技術平臺的動態(tài)模塊化規(guī)范。

我們通過一道面試題來驗證下

class T  implements Cloneable{
  public static int k = 0;
  public static T t1 = new T("t1");
  public static T t2 = new T("t2");
  public static int i = print("i");
  public static int n = 99;
  
  public int j = print("j");
  {
      print("構造塊");
  }
  
  static {
      print("靜態(tài)塊");
  }
  
  public T(String str) {
      System.out.println((++k) + ":" + str + "    i=" + i + "  n=" + n);
      ++n; ++ i;
  }
  
  public static int print(String str){
      System.out.println((++k) +":" + str + "   i=" + i + "   n=" + n);
      ++n;
      return ++ i;
  }
  
  public static void main(String[] args){
      T t = new T("init");
  }
}

好的祠够,現(xiàn)在可以開始分析了压汪。
按照我們之前說的7個階段來說
首先 我們通過
加載->驗證->鏈接【這時候將開始于我們的類內容正式相關】
我們知道鏈接可以細分為3個階段
在第一個準備階段:

準備階段是正式為類變量分配內存并且設置類變量【靜態(tài)變量】初始值的位置

在這里可以理解為 設置
k=0;
t1=null;
t=null;
i=0;
h=0;
然后開始第二個階段解析:這里對執(zhí)行代碼沒有直接影響
當來到第三個階段初始化的時候,就會開始賦值古瓤,我們根據代碼繼續(xù)走著看看止剖。從第一個開始賦值:
k=0;
t1=new T("t1");
這里是對T的實例化,所以會走到T的類變量賦值和構造方法和實際調用方法落君。先走到了
public int j = print("j");
然后調用print方法 輸出:
1:j i=0 n=0
這時候再返回到執(zhí)行完畢的j=1 n=1;
然后調用了初始化塊:在執(zhí)行print("構造快");
這時候輸出
2:構造塊 i=1 n=1
這時候就可以執(zhí)行方法本身的構造方法了輸出
3:t1 i=2 n=2
然后執(zhí)行完了t1實例化的全部過程
繼續(xù)執(zhí)行t2實例化 穿香,
public static T t2 = new T("t2");
過程同t1
4:j j=3 n=3
5:構造塊 j=4 n=4
6:t2 j=5 n=5
然后繼續(xù)執(zhí)行
public static int i = print("i");
7:i j=6 i=6
返回執(zhí)行
public static int n = 99;
此時n=99
然后因為現(xiàn)在處于初始化不會執(zhí)行變量賦值 以及初始化塊和構造函數(shù),因為其實我們還沒有執(zhí)行T t = new T("init");
所以直接跳到
static {
print("靜態(tài)塊");
}
8:靜態(tài)塊 j=7 n=99
然后 初始化完畢 绎速。開始執(zhí)行T t = new T("init");
這時候執(zhí)行
public int j = print("j");
9:j j=8 n=100
執(zhí)行
{
print("構造塊");
}
10:構造塊 j=9 n=101
執(zhí)行構造方法
11:init j=10 n=102
所以答案是

1:j   i=0   n=0
2:構造塊   i=1   n=1
3:t1    i=2  n=2
4:j   i=3   n=3
5:構造快   i=4   n=4
6:t2    i=5  n=5
7:i   i=6   n=6
8:靜態(tài)塊   i=7   n=99
9:j   i=8   n=100
10:構造快   i=9   n=101
11:init    i=10  n=102

總結一下 我們可以知道 在實例化一個類的時候會進行類加載
1.過程中準備階段進行靜態(tài)變量以及靜態(tài)塊的的初始化皮获,這時候是沒有賦值的,為該類的‘零值’纹冤。

2.然后在類的初始化這個階段進行賦值洒宝,賦值的時候只會對使用了static關鍵字的變量賦值购公,將代碼里本來賦給他們的值,真正意義上的賦給他雁歌,并且執(zhí)行靜態(tài)語句塊宏浩。【這個過程只會執(zhí)行一次将宪,因為一個class只會初始化加載一次】
1.2過程都是在虛擬機里run的時候。代碼正式開始運行以前就執(zhí)行了橡庞。

3.當進行實例化的時候只會進行對類變量较坛,初始塊,以及調用的構造方法進行真的實現(xiàn)扒最。而靜態(tài)相關方法只會進行一次丑勤。而且靜態(tài)變量也不會被釋放

那么實例化一個類有幾種方法呢?

首先貼出實例化的類

package com.test;
public class ClassDTO  implements Cloneable,Serializable{
    private String name;
    private Integer age;

    public ClassDTO(Integer age) {
        this.age = age;
    }

    public ClassDTO() {
        this.setName("momo");
        this.setAge(12);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


    @Override
    public Object clone(){
        Object classDTO=null;
        try {
           classDTO= super.clone();

        }catch (Exception e){
            System.out.println("error");
        }
        return classDTO;
    }
}
  1. new 關鍵字
ClassDTO classDTO=new ClassDTO();
  1. 反射,調用java.lang.Class類的newInstance()實例方法
ClassDTO classDTO =(ClassDTO)Class.forName("com.test.ClassDTO").newInstance();

這個方法和new關鍵字的區(qū)別:
這個生成對象只能調用無參的構造函數(shù)吧趣,new 沒有這個限制
這個是創(chuàng)建通過反射創(chuàng)建了一個新的類法竞,所以必須保證這個類已經被加載且鏈接,new使用的是類加載機制强挫,沒有要求
這個效率比較低岔霸,是弱類型,new關鍵字相反

  1. java.lang.reflect.Constructor類的newInstance()實例方法
Constructor<ClassDTO> constructor = 
ClassDTO.class.getConstructor();
ClassDTO classDTO = constructor.newInstance();
  1. clone方法 這個需要重寫cloneable接口
ClassDTO classDTO=new ClassDTO();
ClassDTO classDTO1=(ClassDTO)classDTO.clone();
  1. 反序列機制
ClassDTO classDTO=new ClassDTO();
//寫
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("classDTO.bin"));
output.writeObject(classDTO);
output.close();

//讀
ObjectInputStream input = new ObjectInputStream(new FileInputStream( "classDTO.bin"));
ClassDTO classDTO1 = (ClassDTO) input.readObject();

然后我們就可以開始看java代碼了

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
    private static final int ANNOTATION= 0x00002000; //注釋類型
    private static final int ENUM      = 0x00004000;//枚舉類型
    private static final int SYNTHETIC = 0x00001000;//合成類型

    //注冊本地方法
    private static native void registerNatives();
    static {
        registerNatives();
    }

 //私有方法 給jvm創(chuàng)造創(chuàng)造類的時候使用的
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }

   // 重寫Object的toString
    public String toString() {
//區(qū)別了接口和普通類的
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
            + getName();
    }

  //toString的詳細版
    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();
        }
    }

   //通過類全限定名獲得該類的類對象
    @CallerSensitive //用來找到真正發(fā)起反射請求的類
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }


  //方法返回與給定字符串名的類或接口的Class對象俯渤,使用給定的類加載器呆细。使用指定的加載器加載
    @CallerSensitive
    public static Class<?> forName(String name, boolean initialize,
                                   ClassLoader loader)
        throws ClassNotFoundException
    {
        Class<?> caller = null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Reflective call to get caller class is only needed if a security manager
            // is present.  Avoid the overhead of making this call otherwise.
            caller = Reflection.getCallerClass();
            if (sun.misc.VM.isSystemDomainLoader(loader)) {
                ClassLoader ccl = ClassLoader.getClassLoader(caller);
                if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                    sm.checkPermission(
                        SecurityConstants.GET_CLASSLOADER_PERMISSION);
                }
            }
        }
        return forName0(name, initialize, loader, caller);
    }

    
    private static native Class<?> forName0(String name, boolean initialize,
                                            ClassLoader loader,
                                            Class<?> caller)
        throws ClassNotFoundException;

   //通過newInstance 生成一個類的實例 默認調用無參構造方法
    @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.

        // Constructor lookup
        if (cachedConstructor == null) {
            if (this == Class.class) {
                throw new IllegalAccessException(
                    "Can not call newInstance() on the Class for java.lang.Class"
                );
            }
            try {
                Class<?>[] empty = {};
                final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
                // Disable accessibility checks on the constructor
                // since we have to do the security check here anyway
                // (the stack depth is wrong for the Constructor's
                // security check to work)
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                c.setAccessible(true);
                                return null;
                            }
                        });
                cachedConstructor = c;
            } catch (NoSuchMethodException e) {
                throw (InstantiationException)
                    new InstantiationException(getName()).initCause(e);
            }
        }
        Constructor<T> tmpConstructor = cachedConstructor;
        // Security check (same as in java.lang.reflect.Constructor)
        int modifiers = tmpConstructor.getModifiers();
        if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
            Class<?> caller = Reflection.getCallerClass();
            if (newInstanceCallerCache != caller) {
                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;
        }
    }
 //緩存已經調用的共有方法
    private volatile transient Constructor<T> cachedConstructor;
//緩存class 對象
    private volatile transient Class<?>       newInstanceCallerCache;
//判斷一個對象是否該class的實例
    public native boolean isInstance(Object obj);


  //判斷一個該類和另一個類cls是否相同或是另一個類的子類或接口
    public native boolean isAssignableFrom(Class<?> cls);


  //判斷一個對象實例是否是一個 類/接口的/其子類子接口 的實例
    public native boolean isInterface();


//判斷是否出租
    public native boolean isArray();

    //判斷該Class是否是基本類型+特殊類型,
  /**
     * @see     java.lang.Boolean#TYPE
     * @see     java.lang.Character#TYPE
     * @see     java.lang.Byte#TYPE
     * @see     java.lang.Short#TYPE
     * @see     java.lang.Integer#TYPE
     * @see     java.lang.Long#TYPE
     * @see     java.lang.Float#TYPE
     * @see     java.lang.Double#TYPE
     * @see     java.lang.Void#TYPE 特殊類型
   */
    public native boolean isPrimitive();

      //判斷該Class是否是注釋類型
    public boolean isAnnotation() {
        return (getModifiers() & ANNOTATION) != 0;
    }

    //判斷是否合成類型(  是由編譯器引入的字段八匠、方法絮爷、類或其他結構)
    public boolean isSynthetic() {
        return (getModifiers() & SYNTHETIC) != 0;
    }

// 獲取類名
    public String getName() {
        String name = this.name;
        if (name == null)
            this.name = name = getName0();
        return name;
    }

    // cache the name to reduce the number of calls into the VM
    private transient String name;
    private native String getName0();

  //返回類加載器
    @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; }

    // Initialized in JVM not by private constructor
    // This field is filtered from reflection access, i.e. getDeclaredField
    // will throw NoSuchFieldException
    private final ClassLoader classLoader;

//返回該類中變量字段的類型變量數(shù)組
    @SuppressWarnings("unchecked")
    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];
    }


    //獲得該類的直接父類的Class對象,如果該類是接口梨树,則返回null
    public native Class<? super T> getSuperclass();


  //返回詳細版的父類class對象
    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();
    }

    //獲取類的包路徑
    public Package getPackage() {
        return Package.getPackage(this);
    }


    //獲取該類直接實現(xiàn)的所有接口的數(shù)組
    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();
        }
    }

    private native Class<?>[] getInterfaces0();

 //獲取所有接口坑夯,同上面的不同之處在于,若超接口是參數(shù)化類型(泛型)則返回的是其實際類型
    public Type[] getGenericInterfaces() {
        ClassRepository info = getGenericInfo();
        return (info == null) ?  getInterfaces() : info.getSuperInterfaces();
    }


    //返回數(shù)組類型抡四,若該類不是數(shù)組柜蜈,返回null
    public native Class<?> getComponentType();


  //返回修飾符對應的int值
    public native int getModifiers();


    /**
     * Gets the signers of this class.
     *
     * @return  the signers of this class, or null if there are no signers.  In
     *          particular, this method returns null if this object represents
     *          a primitive type or void.
     * @since   JDK1.1
     */
    public native Object[] getSigners();


    /**
     * Set the signers of this class.
     */
    native void setSigners(Object[] signers);

//如果這個類是本地或匿名類,返回的底層類的立即封閉方法指巡,否則返回null跨释。
    @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 final static class EnclosingMethodInfo {
        private Class<?> enclosingClass;
        private String name;
        private String descriptor;

        private EnclosingMethodInfo(Object[] enclosingInfo) {
            if (enclosingInfo.length != 3)
                throw new InternalError("Malformed enclosing method information");
            try {
                // The array is expected to have three elements:

                // the immediately enclosing class
                enclosingClass = (Class<?>) enclosingInfo[0];
                assert(enclosingClass != null);

                // the immediately enclosing method or constructor's
                // name (can be null).
                name            = (String)   enclosingInfo[1];

                // the immediately enclosing method or constructor's
                // descriptor (null iff name is).
                descriptor      = (String)   enclosingInfo[2];
                assert((name != null && descriptor != null) || name == descriptor);
            } catch (ClassCastException cce) {
                throw new InternalError("Invalid type in enclosing method information", cce);
            }
        }

        boolean isPartial() {
            return enclosingClass == null || name == null || descriptor == null;
        }

        boolean isConstructor() { return !isPartial() && "<init>".equals(name); }

        boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }

        Class<?> getEnclosingClass() { return enclosingClass; }

        String getName() { return name; }

        String getDescriptor() { return descriptor; }

    }

    private static Class<?> toClass(Type o) {
        if (o instanceof GenericArrayType)
            return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
                                     0)
                .getClass();
        return (Class<?>)o;
     }

//如果這個類是本地或匿名類,返回的底層類的立即封閉構造方法厌处,否則返回null鳖谈。
    @CallerS    @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");
        }
    }


//返回一個 Constructor 對象,該對象反映此 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();


  //如果這個類是本地或匿名類,返回底層類的立即封閉類缆娃。
    @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;
    }

   //獲取源代碼中給出的“底層類”簡稱捷绒,木有包名,如果是個匿名函數(shù)則返回空空字符串贯要。注意和getName區(qū)分
    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
        // name of non-package classes (not top level) is the binary
        // name of the immediately enclosing class followed by a '$' followed by:
        // (for nested and inner classes): the simple name.
        // (for local classes): 1 or more digits followed by the simple name.
        // (for anonymous classes): 1 or more digits.

        // Since getSimpleBinaryName() will strip the binary name of
        // the immediatly enclosing class, we are now looking at a
        // string that matches the regular expression "\$[0-9]*"
        // followed by a simple name (considering the simple of an
        // anonymous class to be the empty string).

        // Remove leading "\$[0-9]*" from the name
        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);
    }

    /**
     * Return an informative string for the name of this type.
     *
     * @return an informative string for the name of this type
     * @since 1.8
     */
    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();
    }

    ////判斷字符是否是ASCII碼
    private static boolean isAsciiDigit(char c) {
        return '0' <= c && c <= '9';
    }

    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();
        }
    }

  //判斷是否是注釋類型
    public boolean isAnonymousClass() {
        return "".equals(getSimpleName());
    }

  //判斷是否是局部類
    public boolean isLocalClass() {
        return isLocalOrAnonymousClass() && !isAnonymousClass();
    }

   //判斷是否是成員類
    public boolean isMemberClass() {
        return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
    }

    /**
     * Returns the "simple binary name" of the underlying class, i.e.,
     * the binary name without the leading enclosing class name.
     * Returns {@code null} if the underlying class is a top level
     * class.
     */
    private String getSimpleBinaryName() {
        Class<?> enclosingClass = getEnclosingClass();
        if (enclosingClass == null) // top level class
            return null;
        // Otherwise, strip the enclosing class' name
        try {
            return getName().substring(enclosingClass.getName().length());
        } catch (IndexOutOfBoundsException ex) {
            throw new InternalError("Malformed class name", ex);
        }
    }

  //局部類和匿名類返回true
    private boolean isLocalOrAnonymousClass() {
        // 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.
        return getEnclosingMethodInfo() != null;
    }

    //獲取該類中所有公有的成員類
    @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]);
                }
            });
    }

//獲取所有公有字段
    @CallerSensitive
    public Field[] getFields() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyFields(privateGetPublicFields(null));
    }

//獲取所有公有方法
    @CallerSensitive
    public Method[] getMethods() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyMethods(privateGetPublicMethods());
    }


//獲取所有公有構造器
    @CallerSensitive
    public Constructor<?>[] getConstructors() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyConstructors(privateGetDeclaredConstructors(true));
    }


//根據名稱獲取字段
    @CallerSensitive
    public Field getField(String name)
        throws NoSuchFieldException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        Field field = getField0(name);
        if (field == null) {
            throw new NoSuchFieldException(name);
        }
        return field;
    }


 //根據方法名稱獲取方法信息暖侨,后面的變長參數(shù)是該方法的每一個參數(shù)的對應的Class類型
    @CallerSensitive
    public Method getMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        Method method = getMethod0(name, parameterTypes, true);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }


  // 根據構造器名稱獲取構造器信息,后面的變長參數(shù)是該構造器的每一個參數(shù)的對應的Class類型
    @CallerSensitive
    public Constructor<T> getConstructor(Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return getConstructor0(parameterTypes, Member.PUBLIC);
    }


    //返回類中所有內部類崇渗,這里的類包括數(shù)組字逗、接口等
    @CallerSensitive
    public Class<?>[] getDeclaredClasses() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
        return getDeclaredClasses0();
    }


    //返回類中成員字段
    @CallerSensitive
    public Field[] getDeclaredFields() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyFields(privateGetDeclaredFields(false));
    }

//返回類中成員字段
    @CallerSensitive
    public Method[] getDeclaredMethods() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyMethods(privateGetDeclaredMethods(false));
    }

//返回類中所有構造器
    @CallerSensitive
    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyConstructors(privateGetDeclaredConstructors(false));
    }


  //返回對應的字段Field對象
    @CallerSensitive
    public Field getDeclaredField(String name)
        throws NoSuchFieldException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        Field field = searchFields(privateGetDeclaredFields(false), name);
        if (field == null) {
            throw new NoSuchFieldException(name);
        }
        return field;
    }


  //返回對應的Method對象,name是方法名稱,parameterTypes是對應形參
    @CallerSensitive
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }


    //getDeclaredMethod():對給出的name獲取對應的類中的方法(Method對象)
 * 若不存在宅广,則拋出NoSuchMethodException異常
    @CallerSensitive
    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return getConstructor0(parameterTypes, Member.DECLARED);
    }

 //獲取參數(shù)中指定的資源葫掉,以字節(jié)流返回
     public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }

  //返回指定的資源 url格式
    public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResource(name);
        }
        return cl.getResource(name);
    }

}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跟狱,隨后出現(xiàn)的幾起案子俭厚,更是在濱河造成了極大的恐慌,老刑警劉巖驶臊,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挪挤,死亡現(xiàn)場離奇詭異,居然都是意外死亡关翎,警方通過查閱死者的電腦和手機扛门,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纵寝,“玉大人尖飞,你說我怎么就攤上這事〉暄牛” “怎么了政基?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闹啦。 經常有香客問我沮明,道長,這世上最難降的妖魔是什么窍奋? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任荐健,我火速辦了婚禮,結果婚禮上琳袄,老公的妹妹穿的比我還像新娘江场。我一直安慰自己,他們只是感情好窖逗,可當我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布址否。 她就那樣靜靜地躺著,像睡著了一般碎紊。 火紅的嫁衣襯著肌膚如雪佑附。 梳的紋絲不亂的頭發(fā)上樊诺,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天,我揣著相機與錄音音同,去河邊找鬼词爬。 笑死,一個胖子當著我的面吹牛权均,可吹牛的內容都是我干的顿膨。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼叽赊,長吁一口氣:“原來是場噩夢啊……” “哼恋沃!你這毒婦竟也來了?” 一聲冷哼從身側響起蛇尚,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤芽唇,失蹤者是張志新(化名)和其女友劉穎顾画,沒想到半個月后取劫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡研侣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年谱邪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庶诡。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡惦银,死狀恐怖,靈堂內的尸體忽然破棺而出末誓,到底是詐尸還是另有隱情扯俱,我是刑警寧澤,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布喇澡,位于F島的核電站迅栅,受9級特大地震影響,放射性物質發(fā)生泄漏晴玖。R本人自食惡果不足惜读存,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呕屎。 院中可真熱鬧让簿,春花似錦、人聲如沸秀睛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹂安。三九已至居凶,卻和暖如春虫给,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侠碧。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工抹估, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弄兜。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓药蜻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親替饿。 傳聞我的和親對象是個殘疾皇子语泽,可洞房花燭夜當晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內容