[英]Java Case Sensitivity: Class file collision: A resource exists with a different case
我在Windows OS中,在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(小寫)類時,我在eclipse中收到一條消息,提示Type with same name but different case exists.
我的問題是:Java區分大小寫。 這是否意味着JVM(基於Windows和UNIX的JVM)區分大小寫,或者編譯器區分大小寫? 以及為什么它在方案1和eclipse中給出該異常,所以不允許我在方案2的相同位置創建employee.java文件。
還請記住,我在Windows OS上,文件名不區分大小寫,因此我知道它將不允許employee.java和Employee.java放在同一位置。 這是否違反Java區分大小寫?
Windows上的文件系統不區分大小寫:Employee.class和employee.class不能駐留在同一目錄中。
場景1中的兩個類都在同一個Java源代碼中定義:創建employee.class的編譯器可能會覆蓋Employee.class或其他內容。
場景2具有單獨的Java源: Eclipse將無法在與Employee.java相同的目錄中(在Windows文件系統下)創建一個employee.java。 因此,過去有人會小心處理用戶友好的錯誤。
Java采用區分大小寫的名稱。
您可以將源代碼帶到Linux,將其編譯為.jar(zip格式,同樣區分大小寫)。 然后將jar復制到Windows並執行。
順便說一句,我想您已經找到了一種混淆Java源代碼的新方法,可以在Windows下反編譯。
一個相關的主題是在類/文件名中使用Unicode字母。 這涉及不同的平台,Unicode的不同規范表示形式( é
作為一個或兩個Unicode代碼點),版本控制系統。
詳細說明:(供有興趣者使用)
人類字符é
在Unicode中有兩種表示形式:
é
; e
,加上組合的變音標記U-0301, ´
(零寬度重音)。 不幸的是,不同的操作系統(有人告訴我)使用不同的規范表示。 我曾經想使用版本控制系統hg,但是不得不找出它們缺少對Linux / Windows互操作性的支持。
否則,可以使用java.text.Normalizer
將其規范化為規范形式。
因此,讓我們等待:
class CaféMañanaFaçade
這不是Java的限制,而是您要在其中寫入文件的Windows文件系統的限制。 在不區分大小寫的文件系統上,編譯器無法將Employee.class
和employee.class
都寫入磁盤,因為就FS而言,它們是同一文件。
如果你能以某種方式做編譯來區分大小寫的文件系統(例如在Linux上),然后打包生成的類文件到一個JAR,那么你將能夠從該JAR沒有Windows錯誤運行,作為一個ZIP文件能夠包含兩個不同的條目,其名稱僅大小寫不同。
無論如何,按照慣例,類名應始終以大寫字母開頭。
該約定有助於避免您描述的問題。
不,不是。 Java區分大小寫,這就是Java自身可以控制的全部。
它無法控制您的文件系統,該文件系統的實現可能不符合Java策略。
我在gradle項目中遇到了這個問題,該項目包含多個子項目,並且來源不同。 其中一個具有讀取com.package.level1.Main
的類,另一個具有com.package.level1.main.Util
。 當我為整個項目運行gradle build時,它在命令行中運行良好,但是Eclipse項目上的紅色驚嘆號很難解決。 消除此問題的方法是刪除該項目的源文件的自動Java編譯,並設置為僅使用gradle。 情況如下:
Project Properties
。 Builders
”。 Java Builder
,僅保留Gradle Project Builder
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.