BytesClassLoader.java
package space.sunqian.common.reflect;
import space.sunqian.annotations.Nonnull;
import space.sunqian.annotations.Nullable;
import space.sunqian.common.Fs;
import space.sunqian.common.base.system.JvmException;
import java.nio.ByteBuffer;
/**
* A class loader provides methods for loading classes from the specified byte data:
* <ul>
* <li>{@link #loadClass(String, byte[])}</li>
* <li>{@link #loadClass(String, ByteBuffer)}</li>
* </ul>
*
* @author sunqian
*/
public class BytesClassLoader extends ClassLoader {
/**
* Loads and returns a class from the specified byte data.
* <p>
* A class should only be loaded once in a loader, so if the class has been loaded before, it will be returned
* directly, or an error thrown if the class name is not specified.
*
* @param name the expected name of the class to load, or null if not known
* @param bytes the specified byte data
* @return the {@link Class} instance loaded from the specified byte data
* @throws JvmException if an exception occurs
*/
public @Nonnull Class<?> loadClass(@Nullable String name, @Nonnull byte @Nonnull [] bytes) throws JvmException {
return Fs.uncheck(() -> {
if (name != null) {
Class<?> loaded = findLoadedClass(name);
if (loaded != null) {
return loaded;
}
}
return defineClass(null, bytes, 0, bytes.length);
}, JvmException::new);
}
/**
* Loads and returns a class from the specified byte data.
* <p>
* A class should only be loaded once in a loader, so if the class has been loaded before, it will be returned
* directly, or an error thrown if the class name is not specified.
*
* @param name the expected name of the class to load, or null if not known
* @param bytes the specified byte data
* @return the {@link Class} instance loaded from the specified byte data
* @throws JvmException if an exception occurs
*/
public @Nonnull Class<?> loadClass(@Nullable String name, @Nonnull ByteBuffer bytes) throws JvmException {
return Fs.uncheck(() -> {
if (name != null) {
Class<?> loaded = findLoadedClass(name);
if (loaded != null) {
return loaded;
}
}
return defineClass(null, bytes, null);
}, JvmException::new);
}
}