亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
反射定義
反射提供的功能:
反射的使用場景
%%PRE_BLOCK_3%%
傳回建構(gòu)器的實(shí)例後,可以根據(jù)外部進(jìn)行進(jìn)行型別轉(zhuǎn)換,從而使用介面或方法進(jìn)行呼叫實(shí)例功能了。
首頁 Java Java基礎(chǔ) 超詳細(xì)的JVM反射原理技術(shù)點(diǎn)總結(jié)哦~

超詳細(xì)的JVM反射原理技術(shù)點(diǎn)總結(jié)哦~

Oct 10, 2020 pm 05:20 PM

java基礎(chǔ)專欄今天介紹超詳細(xì)的JVM反射原理技術(shù)點(diǎn)總結(jié)哦。

超詳細(xì)的JVM反射原理技術(shù)點(diǎn)總結(jié)哦~

反射定義

1,JAVA反射機(jī)制是在運(yùn)行狀態(tài)中

#對於任意一個類,都能夠知道這個類別的所有屬性和方法;

對於任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;

這種動態(tài)獲取的資訊以及動態(tài)呼叫物件的方法的功能稱為java語言的反射機(jī)制。

反射提供的功能:

  • 在執(zhí)行階段判斷任意一個物件所屬的類別
  • 在執(zhí)行時建構(gòu)任意一個類別的物件
  • 在執(zhí)行時判斷任何一個類別所具有的成員變數(shù)和方法
  • 在執(zhí)行階段呼叫任何一個物件的方法

? ??#(如果屬性是private,則正常情況下方是不允許外界操作屬性值,這裡可以用Field類別的setAccessible(true)方法,暫時開啟操作的權(quán)限)

反射的使用場景

    ##Java編碼時知道類別和物件的具體訊息,此時直接對類別和物件進(jìn)行操作即可,無需反射
  • 如果編碼時不知道類別或物件的具體訊息,此時應(yīng)該使用反射來實(shí)現(xiàn)
反射原始碼解析

範(fàn)例API :?

Class.forName("com.my.reflectTest").newInstance()復(fù)制代碼

1. 反射取得類別實(shí)例Class.forName("xxx");

#  先調(diào)用了java.lang.Class 的靜態(tài)方法,取得類別資訊!

注意:forName()反射獲取類別信息,並沒有將實(shí)作留給了java,而是交給了jvm去加載!

? ? ? ? ? 主要是先取得 ClassLoader, 然後呼叫 native 方法,取得信息,載入類別則是回呼 入?yún)lassLoader 進(jìn)類別載入!

 @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        // 先通過反射,獲取調(diào)用進(jìn)來的類信息,從而獲取當(dāng)前的 classLoader
        Class<?> caller = Reflection.getCallerClass();
        // 調(diào)用native方法進(jìn)行獲取class信息
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }復(fù)制代碼

2.?java.lang.ClassLoader-----loadClass()

// java.lang.ClassLoader
    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        // 先獲取鎖
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            // 如果已經(jīng)加載了的話,就不用再加載了
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    // 雙親委托加載
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
 
                // 父類沒有加載到時,再自己加載
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);
 
                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
    
    protected Object getClassLoadingLock(String className) {
        Object lock = this;
        if (parallelLockMap != null) {
            // 使用 ConcurrentHashMap來保存鎖
            Object newLock = new Object();
            lock = parallelLockMap.putIfAbsent(className, newLock);
            if (lock == null) {
                lock = newLock;
            }
        }
        return lock;
    }
    
    protected final Class<?> findLoadedClass(String name) {
        if (!checkName(name))
            return null;
        return findLoadedClass0(name);
    }復(fù)制代碼

3. newInstance()?

newInstance() 其實(shí)相當(dāng)于調(diào)用類的無參構(gòu)造函數(shù),主要做了三件事復(fù)制代碼

  • #權(quán)限偵測,如果不透過直接拋出例外;

  • 尋找無參構(gòu)器,並將其快取起來;

  • ##呼叫特定方法的無參建構(gòu)方法,產(chǎn)生實(shí)例並回傳;
  • // 首先肯定是 Class.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
            // newInstance() 其實(shí)相當(dāng)于調(diào)用類的無參構(gòu)造函數(shù),所以,首先要找到其無參構(gòu)造器
            if (cachedConstructor == null) {
                if (this == Class.class) {
                    // 不允許調(diào)用 Class 的 newInstance() 方法
                    throw new IllegalAccessException(
                        "Can not call newInstance() on the Class for java.lang.Class"
                    );
                }
                try {
                    // 獲取無參構(gòu)造器
                    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&#39;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 {
                // 調(diào)用無參構(gòu)造器
                return tmpConstructor.newInstance((Object[])null);
            } catch (InvocationTargetException e) {
                Unsafe.getUnsafe().throwException(e.getTargetException());
                // Not reached
                return null;
            }
        }復(fù)制代碼
  • 4. getConstructor0() 為取得符合的建構(gòu)子器;分三步驟:

  1. 先取得所有的constructors, 然後透過進(jìn)行參數(shù)類型比較;   2. 找到匹配後,透過 ReflectionFactory copy一份constructor返回;   3. 否則拋出 NoSuchMethodException;

private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
                                        int which) throws NoSuchMethodException
    {
        // 獲取所有構(gòu)造器
        Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
        for (Constructor<T> constructor : constructors) {
            if (arrayContentsEq(parameterTypes,
                                constructor.getParameterTypes())) {
                return getReflectionFactory().copyConstructor(constructor);
            }
        }
        throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
    }復(fù)制代碼

5.?privateGetDeclaredConstructors(), 取得所有的建構(gòu)器主要步驟;

  1. 先嘗試從快取中取得; 2. 如果快取沒有,則從jvm中重新獲取,並存入緩存,快取使用軟引用進(jìn)行保存,保證記憶體可用;

// 獲取當(dāng)前類所有的構(gòu)造方法,通過jvm或者緩存
    // Returns an array of "root" constructors. These Constructor
    // objects must NOT be propagated to the outside world, but must
    // instead be copied via ReflectionFactory.copyConstructor.
    private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
        checkInitted();
        Constructor<T>[] res;
        // 調(diào)用 reflectionData(), 獲取保存的信息,使用軟引用保存,從而使內(nèi)存不夠可以回收
        ReflectionData<T> rd = reflectionData();
        if (rd != null) {
            res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;
            // 存在緩存,則直接返回
            if (res != null) return res;
        }
        // No cached value available; request value from VM
        if (isInterface()) {
            @SuppressWarnings("unchecked")
            Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
            res = temporaryRes;
        } else {
            // 使用native方法從jvm獲取構(gòu)造器
            res = getDeclaredConstructors0(publicOnly);
        }
        if (rd != null) {
            // 最后,將從jvm中讀取的內(nèi)容,存入緩存
            if (publicOnly) {
                rd.publicConstructors = res;
            } else {
                rd.declaredConstructors = res;
            }
        }
        return res;
    }
    
    // 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);
    }
    
    // 新創(chuàng)建緩存,保存反射信息
    private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
                                                int classRedefinedCount) {
        if (!useCaches) return null;
 
        // 使用cas保證更新的線程安全性,所以反射是保證線程安全的
        while (true) {
            ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
            // try to CAS it...
            if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
                return rd;
            }
            // 先使用CAS更新,如果更新成功,則立即返回,否則測查當(dāng)前已被其他線程更新的情況,如果和自己想要更新的狀態(tài)一致,則也算是成功了
            oldReflectionData = this.reflectionData;
            classRedefinedCount = this.classRedefinedCount;
            if (oldReflectionData != null &&
                (rd = oldReflectionData.get()) != null &&
                rd.redefinedCount == classRedefinedCount) {
                return rd;
            }
        }
    }復(fù)制代碼

另外,使用relactionData() 進(jìn)行快取保存;ReflectionData 的資料結(jié)構(gòu)如下!

// reflection data that might get invalidated when JVM TI RedefineClasses() is called
    private static class ReflectionData<T> {
        volatile Field[] declaredFields;
        volatile Field[] publicFields;
        volatile Method[] declaredMethods;
        volatile Method[] publicMethods;
        volatile Constructor<T>[] declaredConstructors;
        volatile Constructor<T>[] publicConstructors;
        // Intermediate results for getFields and getMethods
        volatile Field[] declaredPublicFields;
        volatile Method[] declaredPublicMethods;
        volatile Class<?>[] interfaces;
 
        // Value of classRedefinedCount when we created this ReflectionData instance
        final int redefinedCount;
 
        ReflectionData(int redefinedCount) {
            this.redefinedCount = redefinedCount;
        }
    }復(fù)制代碼

6.透過上面,取得到 Constructor 了!接下來就只要呼叫其對應(yīng)建構(gòu)器的 newInstance(),也就是回傳實(shí)例了!

// return tmpConstructor.newInstance((Object[])null); 
    // java.lang.reflect.Constructor
    @CallerSensitive
    public T newInstance(Object ... initargs)
        throws InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, null, modifiers);
            }
        }
        if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");
        ConstructorAccessor ca = constructorAccessor;   // read volatile
        if (ca == null) {
            ca = acquireConstructorAccessor();
        }
        @SuppressWarnings("unchecked")
        T inst = (T) ca.newInstance(initargs);
        return inst;
    }
    // sun.reflect.DelegatingConstructorAccessorImpl
    public Object newInstance(Object[] args)
      throws InstantiationException,
             IllegalArgumentException,
             InvocationTargetException
    {
        return delegate.newInstance(args);
    }
    // sun.reflect.NativeConstructorAccessorImpl
    public Object newInstance(Object[] args)
        throws InstantiationException,
               IllegalArgumentException,
               InvocationTargetException
    {
        // We can&#39;t inflate a constructor belonging to a vm-anonymous class
        // because that kind of class can&#39;t be referred to by name, hence can&#39;t
        // be found from the generated bytecode.
        if (++numInvocations > ReflectionFactory.inflationThreshold()
                && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
            ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
                new MethodAccessorGenerator().
                    generateConstructor(c.getDeclaringClass(),
                                        c.getParameterTypes(),
                                        c.getExceptionTypes(),
                                        c.getModifiers());
            parent.setDelegate(acc);
        }
 
        // 調(diào)用native方法,進(jìn)行調(diào)用 constructor
        return newInstance0(c, args);
    }復(fù)制代碼

傳回建構(gòu)器的實(shí)例後,可以根據(jù)外部進(jìn)行進(jìn)行型別轉(zhuǎn)換,從而使用介面或方法進(jìn)行呼叫實(shí)例功能了。

相關(guān)免費(fèi)學(xué)習(xí)推薦:
java基礎(chǔ)

以上是超詳細(xì)的JVM反射原理技術(shù)點(diǎn)總結(jié)哦~的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72