日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java.lang.String_自己写的java.lang.String可以让jvm加载到吗?

發布時間:2025/4/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.lang.String_自己写的java.lang.String可以让jvm加载到吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

git

前言

老問題了,到網上也一搜一堆答案,比如,隨便來一篇

乍一看好像沒什么問題,但是在掌握自定義類加載器之后,知道如何打破雙親委派之后再回頭來看這段話發現有兩個問題:

1:憑什么你認為我現在是ApplicationClassLoader? 畢竟很多框架都會自定義類加載器的

2: 憑什么你認為我一定要走雙親委派?

懷疑當然要有個證據,那么我們就寫一段程序:

1:打破雙親委派

2:寫一個java.lang.String類

代碼見git

《2020最新Java基礎精講視頻教程和學習路線!》

一些重要的地方截取出來看看package java.lang;

public class String {

private Integer a;

public Integer getA() {

return a;

}

public void setA(Integer a) {

this.a = a;

}

}package org.wayne;

import org.wayne.util.ClassLoaderUtil;

import java.lang.reflect.Method;

public class RegisterDriverUtil {

public static void register(String name){

Class pluginClass = ClassLoaderUtil.getPluginClass(RegisterDriverUtil.class);

try {

Method method = pluginClass.getDeclaredMethod("register", String.class);

method.setAccessible(true);

method.invoke(pluginClass.newInstance(),name);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

}package org.wayne;

public class RegisterDriverUtil {

public void register(String name) throws ClassNotFoundException {

Class.forName(name);

}

}public static void test8(){

EnvironmentUtil.setEnv(EnvEnum.A);

RegisterDriverUtil.register("java.lang.String");

EnvironmentUtil.clearEnv();

}

打包,在wsl下運行,結果如下

推測:

1:代碼里是用自定義類加載器直接加載的java.lang.String類,并沒有走雙親委派

2:由報錯來看,是java.lang.ClassLoader阻止了加載

原因

無論何種自定義類加載器,最后都是調用的defineClass方法加載byte[],注釋如下

protected final Class> defineClass(String name, byte[] b, int off, int len,

ProtectionDomain protectionDomain)

throws ClassFormatError

{

protectionDomain = preDefineClass(name, protectionDomain);

String source = defineClassSourceLocation(protectionDomain);

Class> c = defineClass1(name, b, off, len, protectionDomain, source);

postDefineClass(c, protectionDomain);

return c;

}

/* Determine protection domain, and check that:

- not define java.* class,

- signer of this class matches signers for the rest of the classes in

package.

*/

private ProtectionDomain preDefineClass(String name,

ProtectionDomain pd)

{

if (!checkName(name))

throw new NoClassDefFoundError("IllegalName: " + name);

// Note: Checking logic in java.lang.invoke.MemberName.checkForTypeAlias

// relies on the fact that spoofing is impossible if a class has a name

// of the form "java.*"

if ((name != null) && name.startsWith("java.")) {

throw new SecurityException

("Prohibited package name: " +

name.substring(0, name.lastIndexOf('.')));

}

if (pd == null) {

pd = defaultDomain;

}

if (name != null) checkCerts(name, pd.getCodeSource());

return pd;

}

結論

1:無論何種自定義類加載器,最終都會調用ClassLoader.defineClass

2:ClassLoader.defineClass中會檢查類名,類名以java.開頭的,不予加載

總結

以上是生活随笔為你收集整理的java.lang.String_自己写的java.lang.String可以让jvm加载到吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。