【问题标题】:Java Case Sensitivity: Class file collision: A resource exists with a different caseJava 大小写敏感性:类文件冲突:资源以不同的大小写存在
【发布时间】:2014-09-12 14:36:37
【问题描述】:

我在 Windows 操作系统中,在 eclipse IDE 中工作,我有以下两种情况:

1.我创建了下面的类,这是在 Employee.java 类中(E 是大写的):

public class Employee {
    public static void main(String[] args) {
        employee emp = new employee();
        emp.test();
    }
}

//here e is in lowercase
class employee {
    public void test() {
        System.out.println("I am in test()");
    }
}

在这种情况下,我得到了以下异常:

Exception in thread "main" java.lang.NoClassDefFoundError: employee (wrong name: Employee)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
.
.
.
at Employee.main(Employee.java:4) // i.e at emp.test();

2。我创建了下面的类,这是 Employee.java 类:

public class Employee {
    public static void main(String[] args) {

    }
}

现在,当我尝试在同一个包中创建 employee.java(e 为小写)类时,我在 eclipse 中收到 Type with same name but different case exists.

的消息

我的问题是:Java 区分大小写。这是否意味着 JVM(基于 Windows 和 UNIX)区分大小写或编译器区分大小写?以及为什么它在场景 1 中给出了该异常,而 Eclipse 不允许我在场景 2 中的同一位置创建 employee.java 文件。

还记得我在 Windows 操作系统上,它对文件名不区分大小写,所以我知道它不允许 employee.java 和 Employee.java 在同一个位置。 这是否违反了 Java 区分大小写的规定?

【问题讨论】:

  • Java 区分大小写,但您的文件系统并非总是如此。尝试在 linux 中做同样的事情。
  • This question 类似
  • @greg-449 你是对的。将其标记为 dup

标签: java eclipse


【解决方案1】:

这不是 Java 的限制,而是您尝试写入文件的 Windows 文件系统的限制。在不区分大小写的文件系统上,编译器无法将Employee.classemployee.class 都写入磁盘,因为就 FS 而言,它们是同一个文件。

如果您能以某种方式编译到区分大小写的文件系统(例如在 Linux 上),然后将生成的类文件打包到 JAR 中,那么您将能够在 Windows 上从该 JAR 运行而不会出错,作为 ZIP文件能够包含两个不同的条目,它们的名称只是大小写不同。

【讨论】:

  • 但是只创建了一个文件:Employee.class,不是吗?
  • @JeanWaghetti 在 Windows 上,是的。如果您在区分大小写的系统上进行编译,您会得到Employeeemployee(问题在一个.java 文件中有两个不同的类,一个是公开的,另一个不是)。
【解决方案2】:

Windows 上的文件系统不区分大小写:Employee.class 和employee.class 不能位于同一目录中。

场景 1,两个类都定义在同一个 java 源代码中: 创建 employee.class 的编译器可能会覆盖 Employee.class 或其他。

具有单独 java 源的场景 2: Eclipse 无法在与 Employee.java 相同的目录中创建一个employee.java(在 Windows 文件系统下)。因此,过去有人小心翼翼地处理用户友好的错误。

Java 假定名称区分大小写。

您可以将您的源代码带到 Linux,将它们编译为 .jar(一种 zip 格式,同样区分大小写)。然后将jar复制到windows并执行。

顺便说一句,我想你已经找到了一种混淆java源代码的新方法,在Windows下反编译。


一个相关的话题是在类/文件名中使用 Unicode 字母。这涉及到不同的平台、Unicode 的不同规范表示(é 作为一两个 Unicode 代码点)、版本控制系统。

阐述:(感兴趣的人)

人类字符 é 在 Unicode 中有两种表示形式:

  • "\u00E9" - 作为一个代码点 U+00E9, é;
  • “e\u0301” - 作为两个代码点,U+009B,字母 e,加上组合变音符号 U-0301、´(零宽度重音符号)。

不幸的是,不同的操作系统(有人告诉我)使用不同的规范表示。 我曾经想使用版本控制系统 hg,但不得不发现,它们缺少对 Linux/Windows 互操作性的支持。

否则,可以使用java.text.Normalizer 规范化为规范形式。

让我们等待:

class CaféMañanaFaçade

【讨论】:

  • +1 解释得很好,但请详细说明你的最后一点,A related topic is using Unicode letters in class / file names. That touches different platforms, different canonical representations of Unicode (é as one or two Unicode code points), version control systems.
【解决方案3】:

无论如何,按照惯例,类名应始终以大写字母开头。

此约定有助于避免您所描述的问题。

【讨论】:

  • 伙计,我知道转换,但这与转换无关,我的问题是别的,Java 还允许我们以小写形式创建类。
【解决方案4】:

不,它没有; Java 是区分大小写的,而这就是 Java 本身可以控制的全部内容。

它无法控制您的文件系统,其实施可能不遵守 Java 政策。

【讨论】:

    【解决方案5】:

    我在一个包含多个子项目且来源不同的 gradle 项目中遇到了这个问题。其中一个有一个阅读com.package.level1.Main的课程,另一个有com.package.level1.main.Util。当我为整个项目运行 gradle build 时,它从命令行运行良好,但是 Eclipse 项目上的红色感叹号很难解决。如何摆脱这一点是删除项目源文件的自动 Java 编译并设置为仅使用 gradle。它是这样的:

    1. 转到Project Properties
    2. 从左侧窗格中选择Builders
    3. 取消选择 Java Builder 并仅保留 Gradle Project Builder
    4. 应用并关闭属性。
    5. 从工作区中删除项目。删除时,选择不从文件系统中删除文件的选项。
    6. 将项目导入回 Eclipse,您应该就完成了。

    【讨论】:

      猜你喜欢
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 2016-05-30
      相关资源
      最近更新 更多