问题概述:我在CSVFile
项目中有一个Utils
类,它在内部使用openCSV的CSVReader
来加载csv文件。
现在我创建了一个名为MyTester
的新项目,并在其类路径中添加了Utils
,目的是使用CSVFile
来处理csv文件。
这是迄今为止的样子
MyTester
src
Tester.java
Utils
src
CSVFile.java
lib
opencsv.jar
实例化CSV文件并传入文件路径只需加载csv文件:
import au.com.bytecode.opencsv.CSVReader;
public class CSVFile {
public CSVFile(String filename) {
CSVReader reader = new CSVReader( ... );
// read CSV file
}
}
这很好用。
所以现在我想在一个单独的项目中加载一个csv文件。我使用CSVFile
就是为了它的目的。
import CSVFile;
class Tester {
public static void main(String[] args) {
CSVFile reader = new CSVFile("test.csv");
}
}
当我运行Tester
时,我会在寻找ClassNotFoundException
时获得CSVReader
。 stacktrace的顶部指向CSVFile
构造函数中的行,所以至少我的代码正在做我期望它做的事情。
我熟悉类路径相关的问题,我忘记添加一个必需的jar,所以当我将所需的jar添加到MyTester
项目时,它会按预期工作。
但我不明白为什么我需要这样做。
如果我使用第三方库中定义的类或方法,我不应该对其实现有任何了解。但是在此示例中,我的Tester
课程需要opencsv.jar
,这对我来说没有意义。可能导致问题的原因是什么?
答案 0 :(得分:1)
如果我使用第三方库中定义的类或方法,我不必知道它的实现。
当使用第三方库编译代码时(在大多数情况下) - 如果我的项目A依赖于B.jar,这是由项目提供的,而该项目又具有依赖性在C.jar上,我通常不需要在我的类路径上使用C.jar来编译项目A.
在运行时,它是一个不同的故事。我的项目A中的一些代码第一次访问B.jar中的类中的方法时,JVM将从B.jar加载该类的字节码,初始化该类,然后继续执行相关方法。类似地,如果在从项目B执行方法的过程中,有一个方法调用C.jar中定义的类,JVM也会加载该字节码。因此,C.jar需要在运行时在您的类路径上,但不一定在编译时。
这就是Maven等工具如此受欢迎的原因 - 它们处理传递项目依赖关系,并根据项目依赖项的声明性描述自动为您设置类路径。