Sensibilidad a mayúsculas y minúsculas de los nombres de clase de Java

Si uno escribe dos clases públicas de Java con el mismo nombre que no distingue entre mayúsculas y minúsculas en directorios diferentes, entonces ambas clases no se pueden utilizar en tiempo de ejecución. (Probé esto en Windows, Mac y Linux con varias versiones de HotSpot JVM. No me sorprendería si hubiera otras JVM en las que se puedan usar simultáneamente). Por ejemplo, si creo una clase llamadaa y uno llamadoA al igual que:

// 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";
    }
}

Tres proyectos de eclipse que contienen el código anterior sondisponible desde mi sitio web.

Si intento llamomyCase en ambas clases así:

System.out.println(A.myCase());
System.out.println(a.myCase());

El typechecker tiene éxito, pero cuando ejecuto el archivo de clase generado por el código directamente arriba obtengo:

Excepción en el hilo "main" java.lang.NoClassDefFoundError: testcase / A (nombre incorrecto: testcase / a)

En Java, los nombres en general son sensibles a mayúsculas y minúsculas. Algunos sistemas de archivos (por ejemplo, Windows) no distinguen entre mayúsculas y minúsculas, por lo que no me sorprende que ocurra el comportamiento anterior, pero pareceincorrecto. Desafortunadamente, las especificaciones de Java son extrañamente no comunes sobre qué clases son visibles. losEspecificación del lenguaje Java (JLS), Java SE 7 Edition (Sección 6.6.1, página 166) dice:

Si una clase o tipo de interfaz se declara pública, entonces se puede acceder a ella mediante cualquier código, siempre que la unidad de compilación (§7.3) en la que se declara sea observable.

En la Sección 7.3, el JLS define la observabilidad de una unidad de compilación en términos extremadamente vagos:

Todas las unidades de compilación del paquete java predefinido y sus subpaquetes lang y io son siempre observables. Para todos los demás paquetes,El sistema host determina qué unidades de compilación son observables..

losEspecificación de la máquina virtual de Java es igualmente vago (Sección 5.3.1):

Los siguientes pasos se utilizan para cargar y, por lo tanto, para crear la clase o la interfaz que no forman parte de la interfaz C denotada por [nombre binario] N mediante el cargador de clases bootstrap [...] De lo contrario, la máquina virtual Java pasa el argumento N a una invocación de un método en el cargador de clases bootstrap para buscar una representación supuesta de C de una manera dependiente de la plataforma.

Todo esto lleva a cuatro preguntas en orden descendente de importancia:

¿Hay alguna garantía sobre qué clases se pueden cargar con los cargadores de clases predeterminados en cada JVM? En otras palabras, ¿puedo implementar una JVM válida pero degenerada que no cargue ninguna clase excepto las de java.lang y java.io?Si hay alguna garantía, ¿el comportamiento en el ejemplo anterior viola la garantía (es decir, es el comportamiento un error)?¿Hay alguna manera de hacer HotSpot cargaa yA ¿simultaneamente? ¿Funcionaría escribir un cargador de clases personalizado?

Respuestas a la pregunta(3)

Su respuesta a la pregunta