【发布时间】:2013-09-13 11:08:42
【问题描述】:
如果我在 tomcat 上运行了两个 java 应用程序。应用 A 和 B。 我在应用程序 A 中有一个带有静态变量的公共类,然后应用程序 B 可以访问它。如果不是那为什么?
我在一次采访中被问到这个问题。我说它不能访问。但是不知道是什么原因?
谁能帮忙解答一下。
【问题讨论】:
如果我在 tomcat 上运行了两个 java 应用程序。应用 A 和 B。 我在应用程序 A 中有一个带有静态变量的公共类,然后应用程序 B 可以访问它。如果不是那为什么?
我在一次采访中被问到这个问题。我说它不能访问。但是不知道是什么原因?
谁能帮忙解答一下。
【问题讨论】:
因为每个应用程序都有自己的类加载器,尽管 JVM 是一样的。 有关类加载器的更多信息,请参阅:What is a Java ClassLoader?
【讨论】:
每个应用程序战争都有一个单独的类加载器,所以不,它们不能访问彼此的方法。
但是,这可以使用诸如 RMI 或某些 HTTP Web 服务之类的东西来完成。
【讨论】:
因为每个 WebApp 都分配了自己的类加载器(Tomcat 系统)。
你的确切问题,关于static:
关键是类加载器的结构。一个 JVM 中的两个 ClassLoader 完全有可能分别加载一个类,因此包含静态字段的单独、独立副本。
喜欢阅读:Classloader behaviour on Tomcat with multiple applications
【讨论】:
让我用最简单的方式来表达。
问题:如何访问静态变量? 答案:肯定是使用类名。
我们有一个class,如下:
package com.package1;
public ClassA {
public static String GLOBAL_VARIABLE= "TEST";
}
问题: JVM 如何看到 ClassA。 答案:它看做是ClassLoaderForA.com.package1.ClassA
假设这是使用 Application1 的类加载器加载的
现在,对于第二个应用程序的类加载器,ClassA 不存在。它不会找到它。那么如何从ClassA获取静态字段
【讨论】:
这取决于。在我看来,这个问题不够清楚,无法给出是/否的答案。
如果应用程序以某种方式公开了变量,那么自然地,其他应用程序可以请求获取该值。但这不太可能是问题的目标。但请记住。在采访中,我发现证明你可以批判性地思考和跳出框框总是好的。
我猜他们想看看你是否掌握了静态变量和ClassLoaders 的概念。 Java 应用程序是动态链接的,这意味着在运行时,ClassLoader(取决于应用程序)将执行链接、加载所有库或委托加载。静态变量由类引用。如果您尝试访问静态变量,类'ClassLoader 将尝试查找并加载该类。由于每个应用程序都有自己的ClassLoader,因此每个应用程序都有自己的一组变量。
这与旧语言中的地址空间分离原则没有什么不同。应用程序运行在单独的地址空间中,即使它由同一台机器托管。因此,两个并排运行的应用程序不能简单地寻址另一个应用程序地址空间中的变量,因为这会违反由多个看门狗强制执行的约束。但请注意,地址空间可以显式共享。
【讨论】: