En Java, vous pouvez définir plusieurs classes de niveau supérieur dans un seul fichier, à condition qu'au plus l'une d'entre elles soit publique (voir JLS §7.6 ). Voir ci-dessous par exemple.
Y at - il un nom bien rangé pour cette technique (analogue à
inner
,nested
,anonymous
)?Le JLS indique que le système peut appliquer la restriction selon laquelle ces classes secondaires ne peuvent pas être
referred to by code in other compilation units of the package
, par exemple, elles ne peuvent pas être traitées comme des packages privés. Est-ce vraiment quelque chose qui change entre les implémentations Java?
par exemple, PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Réponses:
Mon nom suggéré pour cette technique (y compris plusieurs classes de niveau supérieur dans un seul fichier source) serait "mess". Sérieusement, je ne pense pas que ce soit une bonne idée - j'utiliserais plutôt un type imbriqué dans cette situation. Ensuite, il est toujours facile de prédire dans quel fichier source il se trouve. Je ne pense pas cependant qu'il existe un terme officiel pour cette approche.
Quant à savoir si cela change réellement entre les implémentations - j'en doute fortement, mais si vous évitez de le faire en premier lieu, vous n'aurez jamais besoin de vous en soucier :)
la source
public int[] foo(int x)[] { return new int[5][5]; }
aussi bien, même si c'est valide.)javac n'interdit pas activement cela, mais il a une limitation qui signifie à peu près que vous ne voudriez jamais faire référence à une classe de niveau supérieur à partir d'un autre fichier à moins qu'elle ait le même nom que le fichier dans lequel elle se trouve.
Supposons que vous ayez deux fichiers, Foo.java et Bar.java.
Foo.java contient:
Bar.java contient:
Disons également que toutes les classes sont dans le même package (et les fichiers sont dans le même répertoire).
Que se passe-t-il si Foo.java fait référence à Baz mais pas à Bar et que nous essayons de compiler Foo.java? La compilation échoue avec une erreur comme celle-ci:
Cela a du sens si vous y réfléchissez. Si Foo.java fait référence à Baz, mais qu'il n'y a pas de Baz.java (ou Baz.class), comment javac peut-il savoir dans quel fichier source chercher?
Si vous dites à la place à javac de compiler Foo.java et Bar.java en même temps, ou même si vous aviez déjà compilé Bar.java (en laissant la Baz.class où javac peut le trouver), cette erreur disparaît. Cela rend cependant votre processus de construction très peu fiable et instable.
Parce que la limitation réelle, qui ressemble plus à «ne fait pas référence à une classe de niveau supérieur d'un autre fichier, sauf si elle a le même nom que le fichier dans lequel elle se trouve ou si vous faites également référence à une classe qui se trouve dans le même fichier nommé la même chose que le fichier "est un peu difficile à suivre, les gens adoptent généralement la convention beaucoup plus simple (bien que plus stricte) de ne mettre qu'une classe de niveau supérieur dans chaque fichier. C'est aussi mieux si jamais vous changez d'avis quant à savoir si une classe doit être publique ou non.
Parfois, il y a vraiment une bonne raison pour laquelle tout le monde fait quelque chose d'une manière particulière.
la source
Je crois que vous appelez simplement
PrivateImpl
ce que c'est: anon-public top-level class
. Vous pouvez également le déclarernon-public top-level interfaces
.par exemple, ailleurs sur SO: classe de premier niveau non publique vs classe imbriquée statique
En ce qui concerne les changements de comportement entre les versions, il y a eu cette discussion sur quelque chose qui "fonctionnait parfaitement" dans 1.2.2. mais a cessé de fonctionner dans 1.4 sur le forum de sun: Java Compiler - impossible de déclarer une classe de premier niveau non publique dans un fichier .
la source
non-public top level class
seule classe dans un fichier, donc cela ne traite pas de la multiplicité.secondary top level types
.Vous pouvez avoir autant de cours que vous le souhaitez
la source
Démo multi-classe à fichier unique.
Je ne connais aucun qui n'a pas cette restriction - tous les compilateurs basés sur des fichiers ne vous permettront pas de faire référence à des classes de code source dans des fichiers qui ne sont pas nommés de la même manière que le nom de la classe. (si vous compilez un fichier multi-classes et placez les classes sur le chemin des classes, alors n'importe quel compilateur les trouvera)
la source
Selon Effective Java 2nd edition (Item 13):
La classe imbriquée peut être statique ou non statique selon que la classe membre a besoin d'accéder à l'instance englobante (article 22).
la source
Oui, vous pouvez, avec des membres statiques publics sur une classe publique externe, comme ceci:
et un autre fichier qui fait référence à ce qui précède:
mettez-les dans le même dossier. Compiler avec:
et courir avec:
la source
Juste pour info, si vous utilisez Java 11+, il y a une exception à cette règle: si vous exécutez votre fichier java directement ( sans compilation ). Dans ce mode, il n'y a aucune restriction sur une seule classe publique par fichier. Cependant, la classe avec la
main
méthode doit être la première du fichier.la source
Non, tu ne peux pas. Mais c'est très possible à Scala:
la source