运行java-cp和实现类加载器之间的区别

运行java-cp和实现类加载器之间的区别,java,jvm,classpath,classloader,Java,Jvm,Classpath,Classloader,我想知道使用-cp命令行开关运行Java应用程序(提供文件夹或JAR列表)和实现类加载器(例如,使用URLClassLoader类)来加载类之间是否存在功能上的差异 示例代码: // -cp approach java -jar <myjar.jar> -cp ~/folder/with/jars 首先,在您的示例中使用类加载器意味着源代码中的硬编码路径,这与-cp不同 另外,您将负责自己加载类,而不是让jvm解析它们。对我来说似乎有很多不必要的额外代码,除非有充分的理由这样做 另

我想知道使用-cp命令行开关运行Java应用程序(提供文件夹或JAR列表)和实现类加载器(例如,使用URLClassLoader类)来加载类之间是否存在功能上的差异

示例代码:

// -cp approach
java -jar <myjar.jar> -cp ~/folder/with/jars

首先,在您的示例中使用类加载器意味着源代码中的硬编码路径,这与
-cp
不同

另外,您将负责自己加载类,而不是让jvm解析它们。对我来说似乎有很多不必要的额外代码,除非有充分的理由这样做


另一个区别(以及类加载器的优点)是能够按需加载它们。

在我的OpenJDK 7中,系统
ClassLoader
sun.misc.Launcher$AppClassLoader
的一个实例,它又是
URLClassLoader
的一个子类,由系统属性
java.class.path
中的文件创建

正如您所看到的,在我的环境中,似乎没有重要的功能差异,尽管存在差异(例如,这个
AppClassLoader
被注册为具有
ClassLoader.registerasParallelable()
,请参见
ClassLoader
javadoc)“并行功能”)


由于Java是可移植的,我想JVM的其他实现可能会使用类似的机制。所以在我看来,不会有重要的功能差异。可能是默认权限策略、扩展等方面的差异,我不考虑这些功能。

“硬编码路径”——假设这些是作为命令行参数提供给程序的。那么它们就不是硬编码的。这会有什么功能上的区别吗?(我的意思是,如果可用的URL相同,那么程序在两种情况下都能加载相同的类吗)。哦,我看得很短:P我不这么认为。一旦类被加载,它将是相同的。
// URLClassLoader approach. urls is an array that points to the .jars under ~/folder/with/jars
URLClassLoader loader = new URLClassLoader(urls);
loader.findClass(...);