write in front
- Today, I will share some
java
small 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
java
Arrays 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 forName
is 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 DriverManager
can 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 forName
a 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 _