This is the 8th day of my participation in the More text Challenge. For details, see more text Challenge

This article is participating in the “Java Theme Month – Java Development in action”. See the link to the event for more details

First, the need for custom class loaders

  1. You need to encrypt the source code. If you want to encrypt your source code, consider defining your own classloader that encrypts the.class file after it is encoded, and then calls your own custom classloader to decrypt it when it is loaded into memory
  2. The source code is limited. When the source of the source code is not from the hard disk (network transmission), you can consider a custom class loader, you can customize the source of the class

Custom class loaders

Let’s implement a custom class loader. We only have one class to focus on, loadClass. We have three methods to focus on: loadClass, findClass, defineClass. This method will convert the byte array into an object and the only other two methods that we need to implement are loadClass, which we don’t have to implement, because if we did, it would break the parent delegate mechanism, so we won’t do it here; All findClass needs to do is find the.class file for the class we want to load, and then call defineClass to convert the binary into a class object

First, create a class

After creating the class, compile IDEA, delete person. Java, copy person. class from target to the root of the project (if you want to copy it elsewhere, you need to change the file name) or use Javac to compile it

package test;
public class Person {
    private String name;
    public Person(a) {}public Person(String name) {
            this.name = name;
        }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString(a) {
        return "Person{" +
                "name='" + name + '\' ' +
                '} '; }}Copy the code

The second step is to create a custom classloader

I’ve annotated all the points that need attention, so look carefully

public class MyClassLoader extends ClassLoader {
    public MyClassLoader(a){}
    public MyClassLoader(ClassLoader classLoader){
        super(classLoader);
    }
    @Override
    protectedClass<? > findClass(String name)throws ClassNotFoundException {
        System.out.println("Enter the custom class loader");
        // Add. Class suffix, complete file name
        File file=new File(name+".class");
        System.out.println(file.getName());
        byte[] bytes=null;
        try {
            bytes=getClassBytes(file);
            System.out.println("bytes.length:"+bytes.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(bytes! =null) {// Add the package name !!!!!!!
            name="test."+name;
            System.out.println(name);
            Class clazz=defineClass(name,bytes,0,bytes.length);
            System.out.println("Class object created");
            if(clazz! =null){
                System.out.println("Returns the Class object loaded by the custom Class loader");
                System.out.println(clazz.getName());
                returnclazz; }}return super.findClass(name);
    }

    /** * obtain the.class file@param file
     * @return
     * @throws Exception
     */
    private byte[] getClassBytes(File file) throws Exception
    {
        // Here we are going to read. Class bytes, so we are going to use a byte stream
        System.out.println("Open byte stream to read. Class files :"+file);
        FileInputStream fis = new FileInputStream(file);
        FileChannel fc = fis.getChannel();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        WritableByteChannel wbc = Channels.newChannel(baos);
        ByteBuffer by = ByteBuffer.allocate(1024);
        while (true) {int i = fc.read(by);
            if (i == 0 || i == -1) {break;
            }
            by.flip();
            wbc.write(by);
            by.clear();
        }
        fis.close();
        System.out.println("Read finished.");
        returnbaos.toByteArray(); }}Copy the code

Finally, test

public class Test {
    public static void main(String[] args) throws Exception{
        MyClassLoader myClassLoader=new MyClassLoader();
        // Do not use this method
// Class clazz=(Class) Class.forName("Person",true,myClassLoader);
        Class clazz=myClassLoader.loadClass("Person");
        System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -");
        System.out.println(clazz.getName());
        Method[] methods= clazz.getMethods();
        for(Method me:methods) { System.out.println(me); }}}Copy the code

Results:

Class file: person. class Read finished bytes.length:797Person Class object is created. Return the Class object loaded by the custom Class loader, test.person -------------- test.personpublic java.lang.String test.Person.toString()
public java.lang.String test.Person.getName()
public void test.Person.setName(java.lang.String)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long.int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
Copy the code

Third, summary

If you want to load all the classes themselves into memory, consider packaging all the.java files into the same folder, then follow the path to the.class file, remove the prefix and add the package name as the class name, and you can load all the classes themselves.

— — — — — — — — — — — — — — —

If you have questions about this article, please comment directly or send me a personal message. If you think it’s good, you can also support me with a “like”

Without permission, shall not be reproduced!

Wechat public number [programmer Xu Xiaobai], attention can be the first time to read the latest articles. There are 50 high frequency college recruitment interview questions prepared by me, as well as various Java learning materials.