如果在不同的目录中写入两个具有相同不区分大小写名称的公共Java类,那么这两个类在运行时都不可用。(我在Windows、Mac和Linux上测试了HotSpot JVM的几个版本。如果有其他JVM可以同时使用,我不会感到惊讶。(例如,如果我创建一个名为a
的类和一个名为A
的类,如下所示:
// lowercase/src/testcase/a.java
package testcase;
public class a {
public static String myCase() {
return "lower";
}
}
// uppercase/src/testcase/A.java
package testcase;
public class A {
public static String myCase() {
return "upper";
}
}
我的网站上提供了三个包含上述代码的eclipse项目。
如果尝试我调用myCase
在两个类上像这样:
System.out.println(A.myCase());
System.out.println(a.myCase());
typechecker成功,但当我运行由上面代码生成的类文件时,我得到:
线程“main”java中出现异常。lang.NoClassDefFoundError:testcase/A(错误名称:testcase/A)
在Java,名称通常区分大小写。一些文件系统(例如:Windows)不区分大小写,所以出现上述行为并不奇怪,但似乎是错误的。不幸的是,Java规范奇怪地不确定哪些类是可见的。Java语言规范(JLS),JavaSE 7版(第6.6.1节,第166页)说:
如果一个类或接口类型被声明为公共的,那么它可以被任何代码访问,前提是声明它的编译单元(§7.3)是可观察的。
在第7.3节中,JLS用极其模糊的术语定义了编译单元的可观测性:
预定义包java及其子包lang和io的所有编译单元始终可见。对于所有其他包,主机系统确定哪些编译单元是可观察的。
Java虚拟机规范同样含糊不清(第5.3.1节):
以下步骤用于加载,从而使用引导类加载器[...]创建由[二进制名称]N表示的非数组类或接口C否则,Java虚拟机将参数N传递给引导类加载器上的方法调用,以依赖于平台的方式搜索所谓的C表示形式。
所有这些导致了四个问题,按重要性的降序排列:
a
和a
?编写自定义类装入器是否可行
不要只考虑文件夹。
为类使用显式的不同命名空间(“包”),也许可以使用文件夹来匹配类。
当我提到“包”时,我不是指“*.JAR”文件,而是指以下概念:
package com.mycompany.mytool;
// "com.mycompany.mytool.MyClass"
public class MyClass
{
// ...
} // class MyClass
当您没有为代码指定包时,java工具(编译器,即,无论什么)假定对所有代码使用相同的全局包。对于几个类似的类,它们有一个文件夹列表,可以在其中查找。
包在代码中类似于“虚拟”文件夹,并应用于类路径或Java安装上的所有包。您可以有几个具有相同ID的类,但是,如果它们位于不同的包中,并且您指定要查找的包,则不会有任何问题。
只要我的2美分,买你的一杯爪哇咖啡
多纳尔精辟的解释没有什么可补充的,但让我简单地思考一下这句话:
...Java具有相同不区分大小写名称的类...
通常,名称和字符串本身从来都不区分大小写,只有这样才能进行解释。第二,Java没有这样的解释。
所以,你所想的正确措辞是:
...Java类,其在不区分大小写的文件系统中的文件表示具有相同的名称...
语言的核心部分,以及支持的实现类。不保证包含您编写的任何类。(普通的JVM将您的类加载到一个独立于引导加载程序的类加载程序中,事实上,普通的引导加载程序通常从JAR中加载它的类,因为这使得部署比一个充满类的大型旧目录结构更高效。)
Java通过将类的全名映射到然后在类路径上搜索的文件名来加载类。因此testcase. a
转到testcase/a.class
和testcase。a
转到testcase/A. class。有些文件系统把这些东西混在一起,当需要一个时,可能会提供另一个。其他人做对了(特别是,JAR文件中使用的ZIP格式的变体是完全区分大小写和可移植的)。Java对此无能为力(尽管IDE可以通过将. class
文件远离本机FS来处理它,但我不知道是否有人真的这样做,JDK的javac
大多数人肯定没那么聪明)。
然而,这并不是这里要注意的唯一一点:类文件在内部知道它们谈论的是什么类。文件中缺少预期的类只意味着加载失败,从而导致您收到的NoClassDefFoundError
。您得到的是一个问题(至少在某种意义上是一个错误部署),它被检测到并得到了可靠的处理。从理论上讲,您可以构建一个类加载器,通过不断搜索来处理这些事情,但为什么要麻烦呢?将类文件放在JAR中将更可靠地修复问题;这些是正确处理的。
更一般地说,如果你经常遇到这个问题,那就在一个具有大小写敏感文件系统的Unix上进行生产构建(推荐像Jenkins这样的CI系统),并找到哪些开发人员用大小写差异命名类,并让它们停止这是非常令人困惑的!
在执行MySQL 数据库给数据表改名时,发现报错,如下: 从提示中可以看出 blog_comment,表已经存在,可登录 MySQL 客户端查看数据表,并没有看到这张表。 提示中所说目标表并不存在。手动执行改名SQLRENAME TABLE blog_Comment TO blog_comment;,报同样错误:Table 'blog_comment' already exists。 从网上找一些
除了 Java 类与属性的名称外,查询语句对大小写并不敏感。 所以 SeLeCT 与 sELEct 以及 SELECT 是相同的,但是 org.hibernate.eg.FOO 并不等价于 org.hibernate.eg.Foo 并且 foo.barSet 也不等价于 foo.BARSET。 本手册中的 HQL 关键字将使用小写字母。很多用户发现使用完全大写的关键字会使查询语句的可读性更强,但我
问题内容: 默认情况下,django的url解算器似乎执行区分大小写的搜索来解析url,并区分’/ Login’和’login’。我的网址格式如下。 谁能指导我,如何使Django URL不区分大小写? 问题答案: 只需放在每个字符串的开头,即: 告诉每个RE不区分大小写地匹配
问题内容: 我正在尝试考虑在PHP中实现不区分大小写的file_exists函数的最快方法。我最好的选择是枚举目录中的文件,并进行strtolower()与strtolower()的比较直到找到匹配项? 问题答案: 我使用注释中的源代码来创建此功能。返回完整路径文件(如果找到),否则返回FALSE。 在文件名中的目录名称上不区分大小写。
问题内容: 这是我的mysql表的架构,即时通讯使用mysql 5 需要敏感的UNIQUE KEY大小写, 它应该允许输入类似(’a’,0)&(’A’,0)的值 尝试将排序规则更改为latin_1和latin_generic_ci 问题答案: 最简单的是在DDL语句上添加, SQLFiddle演示
本文向大家介绍MySQL大小写敏感导致的问题分析,包括了MySQL大小写敏感导致的问题分析的使用技巧和注意事项,需要的朋友参考一下 MYSQL对大小写敏感 见字如面,见标题知内容。你有遇到过因为MYSQL对大小写敏感而被坑的体验吗? 之前看过阿里巴巴Java开发手册,在MySql建表规约里有看到: 【强制】表名、字段名必须使用小写字母或数字 , 禁止出现数字开头,禁止两个下划线中间只 出现数字。数