J'ai rencontré une bizarrerie de la JLS, ou un bug JavaC (pas sûr de quoi). Veuillez lire ce qui suit et fournir une explication, en citant le passage JLS ou l'identifiant Sun Bug, selon le cas.La méthode package-private surchargée provoque l'échec de la compilation - S'agit-il d'un bug JD ou JAVAC?
Supposons que j'ai un projet artificiel avec le code en trois "modules" -
- API - définit l'API cadre - pensez Servlet API
- Impl - définit la mise en œuvre de l'API - pensez Tomcat Servlet
- App - l'application, j'ai écrit
Voici les classes dans chaque module:
API - MessagePrinter.java
package api;
public class MessagePrinter {
public void print(String message) {
System.out.println("MESSAGE: " + message);
}
}
API - MessageHolder.java
(oui, il fait référence à une classe "impl" - voir plus loin)
package api;
import impl.MessagePrinterInternal;
public class MessageHolder {
private final String message;
public MessageHolder(String message) {
this.message = message;
}
public void print(MessagePrinter printer) {
printer.print(message);
}
/**
* NOTE: Package-Private visibility.
*/
void print(MessagePrinterInternal printer) {
printer.print(message);
}
}
Impl - MessagePrinterInternal.java
- Cette classe dépend d'une classe API. Comme son nom l'indique, il est destiné à une utilisation «interne» ailleurs dans mon petit cadre.
package impl;
import api.MessagePrinter;
/**
* An "internal" class, not meant to be added to your
* application classpath. Think the Tomcat Servlet API implementation classes.
*/
public class MessagePrinterInternal extends MessagePrinter {
public void print(String message) {
System.out.println("INTERNAL: " + message);
}
}
Enfin, la classe unique dans le module App ... MyApp.java
import api.MessageHolder;
import api.MessagePrinter;
public class MyApp {
public static void main(String[] args) {
MessageHolder holder = new MessageHolder("Hope this compiles");
holder.print(new MessagePrinter());
}
}
Donc, maintenant je tente de compiler ma petite application, MyApp.java. Supposons que mes fichiers jar API soient exportés via un fichier jar, disons api.jar, et que je sois un bon citoyen, je ne fais référence à ce jar que dans mon classpath - pas à la classe Impl embarquée dans impl.jar.
Maintenant, il y a une faille dans la conception de mon framework, car les classes API ne doivent pas dépendre des classes d'implémentation "internes". Cependant, ce qui est arrivé comme une surprise est que MyApp.java n'a pas compilé du tout.
javac -cp api.jar src\MyApp.java
src\MyApp.java:11: cannot access impl.MessagePrinterInternal class file for impl.MessagePrinterInternal not found
holder.print(new MessagePrinter());
^
1 error
Le problème est que le compilateur essaie de résoudre la version imprimée() à utiliser, en raison de la surcharge de méthode. Cependant, l'erreur de compilation est quelque peu inattendue, car l'une des méthodes est package-private et n'est donc pas visible par MyApp.
Alors, est-ce un bug javac, ou une bizarrerie de la JLS?
compilateur: Sun javac 1.6.0_14
"en raison d'une surcharge de l'opérateur" à "dû à une surcharge de la méthode" – TofuBeer
fixe - merci. – noahlz