1. 主页 > 好文章

反射性能优化技巧:避免Class.forName误用的3种方案

鍏勫紵浠紒浣犱滑鏈夋病鏈夐亣鍒拌繃杩欑鎯呭喌鈥斺€旈」鐩惎鍔ㄧ獊鐒跺彉鎱紝鐐逛釜鎸夐挳瑕佺瓑涓夌鎵嶅搷搴旓紵馃悽 鎴戜笂涓湀灏辨牻鍦ㄨ繖涓潙閲岋紒褰撴椂姝绘椿鏌ヤ笉鍑哄師鍥狅紝鏈€鍚庡彂鐜板眳鐒舵槸鍙嶅皠浠g爜閲孋lass.forName涔辩敤瀵艰嚧鐨勶紒浠婂ぉ灏辨暀浣犱滑涓夋嫑淇濆懡鎶€宸э紝閮芥槸琛€娉崲鏉ョ殑缁忛獙鍟婏紒

璇濊鏈変釜鏂版墜鍦╢or寰幆閲屽啓Class.forName鍔犺浇绫伙紝缁撴灉姣忔寰幆閮介噸鏂板姞杞界被瀵硅薄銆備綘浠寽鎬庝箞鐫€锛熻繖涓搷浣滅洿鎺ユ妸鎺ュ彛鍝嶅簲鏃堕棿浠?00ms骞插埌2000ms锛佹洿绂昏氨鐨勬槸锛岃繖娈典唬鐮佸眳鐒堕€氳繃浜嗘祴璇曠幆澧冿紝鐩村埌涓婄嚎鎵嶆毚闆?..


馃毃 Class.forName鏈夊鍙€曪紵鐪嬭繖涓姣斿疄楠?/h3>

娴嬭瘯10涓囨绫诲姞杞芥搷浣滐紙MacBook Pro M1锛夛細

鍔犺浇鏂瑰紡鑰楁椂(ms)鍐呭瓨鍗犵敤(MB)
鐩存帴new瀵硅薄5832
Class.forName鏃犵紦瀛?/td>4236217
Class.forName鏈夌紦瀛?/td>8935

鐪嬪埌娌★紵鏃犺剳鐢–lass.forName鑳借鎬ц兘鏆磋穼70鍊嶏紒杩欏摢鏄啓浠g爜锛岀畝鐩存槸缁欐湇鍔″櫒涓婂垜锛?/p>


馃挕 鐏甸瓊鎷烽棶锛氫负浠€涔圕lass.forName杩欎箞鑰楋紵

杩欓噷鏈変釜鍐风煡璇嗭細Class.forName()姣忔鎵ц閮戒細鍋氫笁浠跺ぇ浜嬶細

  1. 妫€鏌ョ被鏄惁宸插姞杞?/li>
  2. 瑙﹀彂闈欐€佷唬鐮佸潡鎵ц
  3. 鍒濆鍖栫被鍙橀噺

鐗瑰埆鏄Е鍙戦潤鎬佷唬鐮佸潡杩欑偣锛屾湁娆℃垜鍔犺浇JDBC椹卞姩鏃讹紝Class.forName瀵艰嚧鏁版嵁搴撹繛鎺ユ睜琚噸澶嶅垵濮嬪寲锛岀洿鎺ユ妸鍐呭瓨鎾戠垎浜嗭紒DBA杩界潃鎴戦獋浜嗕笁澶?..


馃殌 绁炴搷浣滀竴锛氱敤绫诲瓧闈㈠父閲忎唬鏇匡紙.class璇硶锛?/h3>
java澶嶅埗
// 閿欒绀鸿寖 鉂?/span>
Class<?> clazz = Class.forName("java.util.ArrayList");

// 姝g‘濮垮娍 鉁?
Class<?> clazz = ArrayList.class;

杩欎釜鏂规硶0鎴愭湰锛佺洿鎺ョ渷鍘荤被鏌ユ壘杩囩▼銆傚疄娴嬪湪Android寮€鍙戜腑锛屾敼鐢?class璇硶鑳借鍙嶅皠閫熷害鎻愬崌40%锛?/p>

浣嗘敞鎰忔湁涓潙锛氭湁浜涘満鏅繀椤荤敤瀛楃涓茬被鍚嶏紙姣斿鍔ㄦ€侀厤缃級锛岃繖鏃跺€欏氨寰楃湅绗簩鎷涗簡...


馃敟 绁炴搷浣滀簩锛氬叏灞€缂撳瓨澶ф硶

涓婃浼樺寲Spring Boot椤圭洰锛屽彂鐜版湁浜烘妸Class.forName鍐欏湪宸ュ叿鏂规硶閲岋細

java澶嶅埗
// 閿欒绀鸿寖锛氭瘡娆¤皟鐢ㄩ兘閲嶆柊鍔犺浇 鉂?/span>
public static Object createInstance(String className) {
    return Class.forName(className).newInstance();
}

// 姝g‘濮垮娍锛氱敤ConcurrentHashMap缂撳瓨 鉁?
private static Map> classCache = new ConcurrentHashMap<>();

public static Object createInstance(String className) {
    Class<?> clazz = classCache.computeIfAbsent(className, k -> {
        try {
            return Class.forName(k);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
    return clazz.newInstance();
}

杩欎釜鏀瑰姩璁㏎PS浠?200椋欏崌鍒?600锛佸唴瀛樺崰鐢ㄧ洿鎺ョ爫鍗婏紒缂撳瓨鐪熸槸涓ソ涓滆タ锛屼絾鍗冧竾璁板緱瑕佸鐞咰lassNotFoundException锛?/p>


鈿?绁炴搷浣滀笁锛氶鍔犺浇绛栫暐

鍋欰ndroid鍚姩浼樺寲鏃跺鍒扮殑鐙犳嫑鈥斺€斿湪Application鍒濆鍖栨椂棰勫姞杞藉父鐢ㄧ被锛?/p>

java澶嶅埗
// 鍚姩鏃堕鍔犺浇
public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        preloadClasses("android.net.Uri", "java.util.concurrent.LinkedBlockingQueue");
    }

    private void preloadClasses(String... classNames) {
        for (String name : classNames) {
            try {
                Class.forName(name);
            } catch (Exception ignored) {}
        }
    }
}

鏌愮數鍟咥PP鐢ㄨ繖鎷涙妸棣栭〉娓叉煋鏃堕棿浠?.2绉掑帇鍒?00ms锛佷笉杩囪娉ㄦ剰鍒鍔犺浇澶绫伙紝鍚﹀垯鍙兘閫傚緱鍏跺弽锛?/p>


馃搳 缂撳瓨鏂规鎬ц兘PK

鏂规閫傜敤鍦烘櫙绾跨▼瀹夊叏鍐呭瓨寮€閿€
HashMap缂撳瓨鍗曠嚎绋嬬幆澧?/td>鉂?/td>浣?/td>
ConcurrentHashMap楂樺苟鍙戝満鏅?/td>鉁?/td>涓瓑
WeakReference缂撳瓨绫绘暟閲忓涓斾笉纭畾鉁?/td>鏈€浣庯紙鍙兘琚獹C鍥炴敹锛?/td>

璇寸湡鐨勶紝澶ч儴鍒嗛」鐩敤ConcurrentHashMap灏卞浜嗐€備笂娆¤鏈変汉鐢≧edis缂撳瓨Class瀵硅薄...杩欏氨灞炰簬璧扮伀鍏ラ瓟浜嗭紒


灏忕紪缈昏溅瀹炲綍

鍘诲勾鐢ㄥ弽灏勫啓瑙勫垯寮曟搸鏃讹紝鑷互涓鸿仾鏄庡湴鍔犱簡涓夌骇缂撳瓨锛?/p>

  1. 鍐呭瓨缂撳瓨
  2. 鏈湴鏂囦欢缂撳瓨
  3. 鏁版嵁搴撳浠界紦瀛?/li>

缁撴灉绾夸笂鍑虹幇绫绘洿鏂颁笉鐢熸晥鐨勯棶棰橈紝鎺掓煡涓夊ぉ鍙戠幇鏄湰鍦版枃浠剁紦瀛樻病娓呯悊锛佹洿鎼炵瑧鐨勬槸锛岃繖涓紦瀛樿璁℃嬁浜嗙粍鍐呯殑"鏈€浣宠繃搴﹁璁″"...


鐙鎬ц兘鏁版嵁

鍘嬫祴鏌愭敮浠樼郴缁燂紙鍙嶅皠璋冪敤鍗犳瘮35%锛夛細

浼樺寲鎺柦骞冲潎鍝嶅簲鏃堕棿閿欒鐜?/th>GC娆℃暟
鏈紭鍖?/td>342ms0.7%12娆?鍒嗛挓
鏂规涓€+浜?/td>89ms0.03%3娆?鍒嗛挓
鍏ㄦ柟妗堜紭鍖?/td>67ms0.01%1娆?鍒嗛挓

鐪嬭繖鏁版嵁锛岃鍙嶅皠浼樺寲鑳借绯荤粺璧锋鍥炵敓閮戒笉澶稿紶锛佷絾鍒囪鈥斺€斾紭鍖栧墠鍏堟墦鏃ュ織鐩戞帶鎬ц兘鐑偣锛屽埆鍍忔垜褰撳勾閭f牱鏃犺剳鐬庝紭鍖栵紒

本文由嘻道妙招独家原创,未经允许,严禁转载