【问题标题】:Calling Class.forName() twice两次调用 Class.forName()
【发布时间】:2016-10-17 15:00:27
【问题描述】:

我目前正在阅读类加载器及其层次结构功能。 如果我调用下面的代码 -

ClassA a=  Class.forName("com.test.ClassA")

据我了解,现在它将在应用程序类加载器的帮助下被初始化并加载到内存中。 我有以下问题:

  1. 如果我再次调用上述代码会发生什么?是否会在内存中为“ClassA”创建新实例,还是会返回相同的加载类引用?
  2. 如果是,根据 javarevisited 的 post,“通过使用单独的 ClassLoader,您还可以从多个源加载相同的类,它们将在 JVM 中被视为不同的类” 它有什么用?

【问题讨论】:

  • 顺便说一句:Class.forName 返回一个 Class 类型的对象,而不是在 forName 中传递的类的实例。 ClassA a= Class.forName("com.test.ClassA") 不正确。应该是Class a= Class.forName("com.test.ClassA")

标签: java class classloader


【解决方案1】:
  1. 您将获得相同的课程。只是测试它。再次加载它并检查是否a1 == a2
  2. 此功能最常使用的可能是应用服务器:您可以在单个服务器中部署多个 Web 应用程序,并且所有应用程序都可以使用相同的类。但他们不应该共享静态变量。如果一个使用库 1.0 中的类 Foo,而另一个使用库 2.0 中的类 Foo,应该没有问题。因此需要用不同的类加载器加载同一个类。

【讨论】:

    【解决方案2】:
    1. 仅当您调用时才会创建新实例:

      ClassA inst = new ClassA();

    如果您调用 Class.forName,则类定义(元数据和字节码)被加载到 JVM 中,加载到称为 HEAP 的托管内存的特殊部分中。通常,应用程序使用此功能将类预加载到 JVM 中,以便以后在应用程序需要时没有延迟。

    1. 例如使用热部署。您正在调试 Java Web 服务器。您发现了一个错误,只想更改(重新加载)一个类,而不是整个应用程序。这里的重点也是“不同的类加载器”。这意味着 java 中的库可以从不同的来源加载:jar、war(档案)、从数据库、从网络。将此与 Windows 的 COM 模型进行比较,其中库必须位于同一文件夹或 /system32/ 文件夹中。

    【讨论】:

      猜你喜欢
      • 2022-12-09
      • 2013-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多