[JAVA cold knowledge] Dynamic loading is not suitable for array classes? How to dynamically load an array class?

write in front


  • Today, I will share some javasmall knowledge points with my friends, mainly around the following points:
  • Since it 数组is a class,
  • 类名So what is it after compilation 类路径?
  • Why do you 动态加载say suitable 数组?
  • How should 动态加载one be 数组?
  • Some content references
    • 《编写高质量代码(改善Java程序的151个建议)》
    • 《深入理解Java虚拟机》

A gentleman does not act rashly, but when he moves, there must be a way. A gentleman does not speak eloquently, but his words must be reasonable. A gentleman does not insist on asking, and when he asks, he must be righteous. A gentleman does not act in vain, and his actions must be upright - Fenghuo Opera Princes "Sword Comes"


1. Since it 数组is a class, what is it after compilation 类名?

Through the following code, we can see that for the basic type array, it is compiled as [+基本类型标识, and for the reference type, it is[L+引用类类路径

package com.liruilong;

import java.util.logging.Logger;

/**
 * @Project_name: workspack
 * @Package: com.liruilong
 * @Description:
 * @Author: [email protected]
 * @WeChat_Official_Accounts: 山河已无恙
 * @blog: https://liruilong.blog.csdn.net/
 * @Date: 2022/2/9  3:08
 */
public class ArrayDemo {
    
    
    static Logger logger = Logger.getAnonymousLogger();

    public static void main(String[] args) {
    
    
        logger.info("基本类型数组编译后类名:" + int[].class.getName());
        logger.info("引用类型数组编译后类名:" + String[].class.getName());

    }

}
二月 09, 2022 3:57:03 上午 com.liruilong.ArrayDemo main
信息: 基本类型数组编译后类名:[I
二月 09, 2022 3:57:03 上午 com.liruilong.ArrayDemo main
信息: 引用类型数组编译后类名:[Ljava.lang.String;

Process finished with exit code 0

javaArrays are a special class in , neither , 基本类型数组nor 引用类型数组do they have a traceable classpath

Array element types and compiled types

element type compiled type
byte[] [B
char[] [C
Double[] [D
Float[] [F
Int[] [I
Long[] [J
Short[] [S
Boolean [WITH
Reference types (such as String) [Lreference type

Second, why dynamic loading is not suitable for arrays

dynamic loading

About dynamic loading, I won’t talk about it here. I believe that everyone is familiar with it. When connecting to the database in the original JDBC编程way, a driver class that connects to the database is usually loaded dynamically through a static block. It will be used here to Class.forName(driver)load the driver class into the in memory.

Of course, this forNameis just to put one , not 类加载to 内存中generate one 实例对象, and it will not be executed 任何方法. How to generate an object for the specific injected driver class and how to register it DriverManagercan generally be achieved 静态块by means of ie 类加载的同时生成实例对象并注册.

We know that in 类加载(加载,验证,准备,解析,初始化)the last step 类初始化, the class constructor is executed <clinit>()方法, which <clinit>()方法is the result 编译器自动收集of the class 所有类变量的赋值动作and the 静态语句块的中的语句merge. The order in which the compiler collects is determined by the order in which the statements appear in the source file.

The following is the source code of the mysql driver class

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.mysql.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    
    
    public Driver() throws SQLException {
    
    
    }

    static {
    
    
        try {
    
    
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
    
    
            throw new RuntimeException("Can't register driver!");
        }
    }
}

why not for arrays

Regarding dynamic loading, you can look at 《深入理解Java虚拟机》it, and come back to our question, why arrays are not suitable for dynamic loading. From the above code, you can know that when forNamea class is loaded, one is needed 类的全路径, or rather 全限定名.

But whether it is 基本类型数组, or 引用类型数组, there is no traceable class path, it is not a specific class, so when loading, it will report an errorjava.lang.ClassNotFoundException

package com.liruilong;


import java.util.logging.Logger;

/**
 * @Project_name: workspack
 * @Package: com.liruilong
 * @Description:
 * @Author: [email protected]
 * @WeChat_Official_Accounts: 山河已无恙
 * @blog: https://liruilong.blog.csdn.net/
 * @Date: 2022/2/9  3:08
 */
public class ArrayDemo {
    
    
    static Logger logger = Logger.getAnonymousLogger();

    public static void main(String[] args) throws ClassNotFoundException {
    
    
        Class.forName("java.lang.String[]");
        Class.forName("int[]");
    }

}

Exception in thread "main" java.lang.ClassNotFoundException: java/lang/String[]
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at com.liruilong.ArrayDemo.main(ArrayDemo.java:19)

Process finished with exit code 1

It is not possible to load directly, so is it feasible to load the compiled type of an array? let's see

package com.liruilong;


import java.util.logging.Logger;

/**
 * @Project_name: workspack
 * @Package: com.liruilong
 * @Description:
 * @Author: [email protected]
 * @WeChat_Official_Accounts: 山河已无恙
 * @blog: https://liruilong.blog.csdn.net/
 * @Date: 2022/2/9  3:08
 */
public class ArrayDemo {
    
    
    static Logger logger = Logger.getAnonymousLogger();

    public static void main(String[] args) throws ClassNotFoundException {
    
    
        Class.forName("[Ljava.lang.String;");
        Class.forName("[I");
    }

}

Bad level value for property: .level
Bad level value for property: java.util.logging.ConsoleHandler.level

Process finished with exit code 0

From the above we can know that an array of objects can be loaded dynamically by loading the compiled classpath, but it is meaningless. It is not possible newInstance()to generate an instance object through a method,在java中数组是定长的,没有长度的数组是不允许存在的。

package com.liruilong;


import java.util.logging.Logger;

/**
 * @Project_name: workspack
 * @Package: com.liruilong
 * @Description:
 * @Author: [email protected]
 * @WeChat_Official_Accounts: 山河已无恙
 * @blog: https://liruilong.blog.csdn.net/
 * @Date: 2022/2/9  3:08
 */
public class ArrayDemo {
    
    
    static Logger logger = Logger.getAnonymousLogger();

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    
    
        Class<String[]> aClass = (Class<String[]>) Class.forName("[Ljava.lang.String;");
        String[] strings = aClass.newInstance();
    }

}

Bad level value for property: .level
Bad level value for property: java.util.logging.ConsoleHandler.level
Exception in thread "main" java.lang.InstantiationException: [Ljava.lang.String;
	at java.lang.Class.newInstance(Class.java:427)
	at com.liruilong.ArrayDemo.main(ArrayDemo.java:20)
Caused by: java.lang.NoSuchMethodException: [Ljava.lang.String;.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.newInstance(Class.java:412)
	... 1 more

Process finished with exit code 1

3. How to dynamically load an array

How to generate an array in a similar way to dynamic loading, we can use the Array array tool class to dynamically load an array.

package com.liruilong;


import java.lang.reflect.Array;
import java.util.logging.Logger;

/**
 * @Project_name: workspack
 * @Package: com.liruilong
 * @Description:
 * @Author: [email protected]
 * @WeChat_Official_Accounts: 山河已无恙
 * @blog: https://liruilong.blog.csdn.net/
 * @Date: 2022/2/9  3:08
 */
public class ArrayDemo {
    
    
    static Logger logger = Logger.getAnonymousLogger();

    public static void main(String[] args)  {
    
    
        String [] strings = (String[]) Array.newInstance(String.class,6);
        logger.info("String数组长度:"+strings.length);
        int[][] ints = (int [][])Array.newInstance(int.class,6,3);
        logger.info("int数组长度:"+ints.length);
    }

}

Bad level value for property: .level
Bad level value for property: java.util.logging.ConsoleHandler.level
Can't set level for java.util.logging.ConsoleHandler
二月 09, 2022 5:15:12 上午 com.liruilong.ArrayDemo main
信息: String数组长度:6
二月 09, 2022 5:15:12 上午 com.liruilong.ArrayDemo main
信息: int数组长度:6

Process finished with exit code 0

Looking at the source code, we will find that this is a native method, implemented in a language such as C or C++

 public static Object newInstance(Class<?> componentType, int length)
        throws NegativeArraySizeException {
    
    
        return newArray(componentType, length);
    }
private static native Object newArray(Class<?> componentType, int length)
        throws NegativeArraySizeException;

Share the dynamic loading of arrays with your friends here, come on in life _

Guess you like

Origin blog.csdn.net/sanhewuyang/article/details/122834530