System.load和System.loadLibrary的区别
当我们在Java中使用本地库来写代码时,通常我们的第一步工作就是先加载相应的本地库。
static {
System.load("D:" + File.separator + "Hello.dll");
}
JDK提供了俩种加载本地库的方法:
. System.load(String filename)
. System.loadLibrary(String libname)
本文就解释一下这俩种方式的区别。
根据Java文档上关于System.load()的描述:
根据传入的文件名参数,加载此本地库。文件名必须是一个绝对路径。
此方法的参数应为一个带有扩展名的绝对文件路径。
根据Java文档上关于System.loadLibrary()的描述:
由给定的库名参数加载对应的本地库。库名参数不能包含任何平台相关的前缀、文件扩展符或路径。
正常情况下,都是从系统库的路径加载库,那么系统库的路径是什么呢? 我们来看一个例子:
static {
System.loadLibrary("Hello");
}
完整的程序如下:
public class TestJNI {
static {
System.loadLibrary("Hello");
}
public static void main(String[] args) {
System.out.println("===========");
}
}
运行程序,可以发现控制台输出如下:
![](https://img.haomeiwen.com/i13084796/d03b224607ff6bc8.png)
上面的异常说,它无法在java.library.path下找到名为Hello的库,那么我们来看一下,java.library.path
是个什么东东?
程序如下:
public class TestJNI {
static {
// System.loadLibrary("Hello");
}
public static void main(String[] args) {
System.out.println("===========");
System.out.println(System.getProperty("java.library.path"));
}
}
运行此程序,可以在控制台看到如下输出:
![](https://img.haomeiwen.com/i13084796/cb00dcd2fc8c6532.png)
由此可知System.getProperty("java.library.path")的值即是系统库的默认路径,loadLibrary方法会主动到此路径下
查找对应的库文件。
区别二
System.load()方法和System.loadLibrary的另一个区别就是,在处理库之间的依赖关系时。
假定现在有俩个库:A.dll 和 B.dll 并且A.dll依赖于B.dll,如果使用System.load("D:/A.dll")的话,
即使B.dll和A.dll位于同一个目录下,也会抛出异常。在这种情形下,JVM知道A.dll依赖于B.dll的话,它就会尝试着
在java.library.path下查找B.dll,如果找不到B.dll就会报错。
在这种情况下,有俩种解决方案:
-
先调用System.load("D:/B.dll"),再调用System.load("D:/A.dll")
-
把A.dll和B.dll 都放在java.library.path下面,之后,再调用System.loadLibrary("A")就可以了。
网友评论