关于反序列化的ClassLoader记录
反序列化会使用ObjectInputStream这个类,这个类会调用resolveClass的方法()
/**
* Load the local class equivalent of the specified stream class * description. Subclasses may implement this method to allow classes to * be fetched from an alternate source. * * <p>The corresponding method in <code>ObjectOutputStream</code> is
* <code>annotateClass</code>. This method will be invoked only once for
* each unique class in the stream. This method can be implemented by * subclasses to use an alternate loading mechanism but must return a * <code>Class</code> object. Once returned, if the class is not an array
* class, its serialVersionUID is compared to the serialVersionUID of the * serialized class, and if there is a mismatch, the deserialization fails * and an {@link InvalidClassException} is thrown.
* * <p>The default implementation of this method in
* <code>ObjectInputStream</code> returns the result of calling
* <pre>
* Class.forName(desc.getName(), false, loader)
* </pre>
* where <code>loader</code> is the first class loader on the current
* thread's stack (starting from the currently executing method) that is * neither the {@linkplain ClassLoader#getPlatformClassLoader() platform
* class loader} nor its ancestor; otherwise, <code>loader</code> is the
* <em>platform class loader</em>. If this call results in a
* <code>ClassNotFoundException</code> and the name of the passed
* <code>ObjectStreamClass</code> instance is the Java language keyword
* for a primitive type or void, then the <code>Class</code> object
* representing that primitive type or void will be returned * (e.g., an <code>ObjectStreamClass</code> with the name
* <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
* Otherwise, the <code>ClassNotFoundException</code> will be thrown to
* the caller of this method. * * @param desc an instance of class <code>ObjectStreamClass</code>
* @return a <code>Class</code> object corresponding to <code>desc</code>
* @throws IOException any of the usual Input/Output exceptions.
* @throws ClassNotFoundException if class of a serialized object cannot
* be found. */protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String name = desc.getName();
try {
return Class.forName(name, false, latestUserDefinedLoader());
} catch (ClassNotFoundException ex) {
Class<?> cl = primClasses.get(name);
if (cl != null) {
return cl;
} else {
throw ex;
}
}
}
其中第一行代码使用了public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
然后用latestUserDefinedLoader()获取最后用户定义的ClassLoader
继续查看latestUserDefinedLoader()的源码
/*
* Returns the first user-defined class loader up the execution stack, * or the platform class loader if only code from the platform or * bootstrap class loader is on the stack. */public static ClassLoader latestUserDefinedLoader() {
ClassLoader loader = latestUserDefinedLoader0();
return loader != null ? loader : ClassLoader.getPlatformClassLoader();
}
大概意思是先去调用native的latestUserDefinedLoader0()方法,如果找不到就返回PlatformClassLoader()【我使用的JDK11】;
我这里测试一般latestUserDefinedLoader0()会返回AppClassLoader
这里测试,latestUserDefinedLoader0()不会返回自定义的上下文类加载器