Comment appeler une méthode d'une classe dynamique + conditionnelle? disons, j'ai besoin de la classe Donc, je dois être capable de: p> EDIT STROR>: EDIT2: strong>: Edit3: strong>:
(la classe est finalement nimbuslookandfeel code>, mais sur certains systèmes, il n'est pas disponible (c'est-à-dire
openjdk-6 code>). p>
(créant ainsi une sous-classe interne anonyme de celui-ci)? LI>
ul> Exemple de code h2>
Maintenant, j'ai édité mon code, comme il a été suggéré, d'intercepter noclassduffoundEfferror code> en utilisant try-capture. Il échoue. Je ne sais pas, si c'est la faute de l'openjdk. I Obtenir
InvocationTargetException Code>, causé par
NOCLASSDEffondError code>. Drôle, que je ne peut pas strud> attraper
InvocationTargetException code>: C'est jeté quand même de toute façon. P>
Cause trouvée: j'étais enveloppé oscillabilité.invokeandwait (...) code> autour de la méthode testée, et que très
invokeantwait code> appelant
noclassdefferror code> lors du chargement du nimbus échoue. p>
Quelqu'un peut-il s'il vous plaît clarifier noclassduffounderror code> peut survenir du tout? Parce qu'il semble que c'est toujours la méthode d'appel, pas la méthode réelle qui utilise la classe non existante. P> p>
5 Réponses :
Vous pouvez utiliser classe a > Classe pour le faire. IE: p> Class c = Class.forName("your.package.YourClass");
Je pensais à cela, mais comment puis-je gérer une méthode d'une classe chargée de manière dynamique (créant ainsi une sous-classe interne anonyme de celle-ci)?
Utilisez BCEC pour générer votre sous-classe dynamique à la volée. p>
Bonne idée, mais n'est-ce pas possible d'une manière plus simple?
Je ne le pense pas. La chose la plus proche intégrée à la JDK est la classe de proxy, mais cela ne sera pas une sous-classe, alors ne vous aide pas. En fin de compte, une nouvelle classe doit être créée à la volée, ce qui signifie générer le bytecode de cette classe et le charger via un chargeur de classe. Java ne fournit pas de nombreuses options à cela sans une bibliothèque tierce partie telle que BCEL.
Oui, les procurations ne sont trompées trompeuses que là-bas pour la mise en œuvre d'interfaces.
ERM, vous ne pouvez pas mettre la classe que vous souhaitez étendre dans le chemin de la classe d'heure de compilée, écrivez votre sous-classe comme d'habitude et à l'exécution, déclencher explicitement la chargement de la sous-classe et gérer toute exception projetée par la liaison qui indique que La superclasse est manquante? P>
Apprenez à le savoir que la classe est disponible (au moment de l'exécution) strong> Comment réussir à remplacer une méthode d'une classe chargée de manière dynamique forte> Pour la complétude, chaque classe que vous écrivez est chargée de manière dynamique par l'environnement d'exécution lorsqu'il est requis. p> Donc, votre code peut ressembler à: p>
Mettez l'utilisation dans un bloc d'essai ...
... et laissez le bloc de prise vide (odeur de code?!). p>
Faites-le simplement et assurez-vous que la dépendance du temps compilé est satisfaite. Vous mélangez des choses ici. Le dépassement a lieu au moment de la compilation, tandis que la classe Chargement est une chose d'exécution. P>
Bonne idée! Je n'étais pas seulement exécutant, mais aussi compilation b> Le code sous OpenJDK 6 code>, donc je suis confus par des erreurs de compilation-temps.
... Bien sûr, la solution optimale me permettrait de compiler éventuellement la classe non existante éventuellement.
En supposant que ce code a été compilé, il ne lancera pas un classnotfoundexception code> mais un
NOCLASSDEffondError code> si
nimbuslookandfeel code> n'est pas là au moment de l'exécution.
@ Pascal thivent code>: Droite! "Exception ClassNotFoundException n'est jamais lancée dans le corps de la déclaration d'essai correspondante". Mais êtes-vous sûr que
noclassduffounderror code> est lancé à l'intérieur de cette méthode b>? (Pas, par exemple, à la classe 'CTOR, Statique CTOR, ... ou quelle que soit ...)
@ java.is.for.desktop avez-vous essayé?
Oui, comme mentionné dans la question modifiée, quelque chose semble avoir tort avec OpenJDK-6: Je reçois une invocationTargetException (causée par NOCLASSDEFFUDEError), qui, étrangement, ne peuvent pas être attrapées.
Ah, n'a pas vu la nouvelle partie dans la question. La stacktrace indique-t-elle où vient l'exception?
Maintenant, j'ai trouvé la cause, ajoutée à la question ( Edit2 B>).
Le code suivant doit résoudre votre problème. La classe Ce qui suit est la classe Ce qui suit est l'interface délicate Ce qui suit est la classe principale: p> Pourquoi cela compile et courait-il? B> Comment Ça marche? B> alors, Si Puis, si (En fait, vous n'avez pas à séparer le Si vous avez formulé Que si la classe arrive à la chaîne Et si je veux faire référence à Bien sûr, vous devez modifier l'interface Comment compiler et exécuter le code? B> dans la première exécution, la classe Pour vous aider à définir ma solution à votre problème, voici un lien vers la bonne façon de la bonne façon de définir le look Nimbus et ressentez: p> principale code> simule votre classe principale. Classe
A code> simule la classe de base que vous souhaitez étendre (et vous n'avez aucun contrôle). Classe
B code> est la classe dérivée de la classe
A code>. Interface
C code> simule la fonctionnalité "Fonction Pointer" que Java n'a pas. Voyons le code d'abord ...
A code>, la classe que vous souhaitez prolonger, mais sans contrôle de: p>
B code>, la classe dérivée mannequin. Notez que, puisqu'il étend
a code>, il doit importer
packagea.a code> et classe
A code> doit être disponible à l'heure de la compilation de la classe
B code>. Un constructeur avec paramètre C est essentiel, mais la mise en œuvre d'interface
C code> est facultative. Si
B code> implémente
C code>, vous gagnez la commodité pour appeler la méthode (s) sur une instance de
B code> directement (sans réfléchir). Dans
b.dosomething () code>, appeler
super.dosomething () code> est facultatif et dépend de ce que vous voulez, mais appelez
c.dosomething () code > est essentiel (expliqué ci-dessous): p>
c code>. Il suffit de mettre toutes les méthodes que vous souhaitez remplacer dans cette interface: p>
Vous pouvez voir que dans la classe principale code>, uniquement
packagec.c code> est importé et il n'y a aucune référence à
packagea.a code> ou
ou
ou
ou
paquetb.b code>. S'il y en a un, le chargeur de classe lancera une exception sur les plates-formes qui n'ont pas
packagea.a code> quand il essaie de charger l'un d'entre eux. P>
Dans la première class.forname () code>, il vérifie si la classe
A code> est disponible sur la plate-forme. Si c'est le cas, demandez au chargeur de classe de charger la classe
B code> et stockez l'objet de classe code> résultant code> dans
classb code>. Sinon,
classnotfoundexception code> est lancé par
class.forname () code>, et le programme va sans classe
a code>. P>
Classb code> n'est pas NULL, obtenez le constructeur de la classe
B code> qui accepte un seul objet
c code> comme paramètre. Stockez le
Constructeur Code> Objet dans
Constructorb CODE>. P>
constructurb code> n'est pas null, invoquer
constructorb.newinstance () code> pour créer un objet
B code>. Comme il existe un objet
C code> comme paramètre, vous pouvez créer une classe anonyme qui implémente l'interface
C code> et transmet l'instance comme valeur de paramètre. Ceci est juste comme ce que vous faites lorsque vous créez un Mouselistener anonyme code>. P>
Essayer ci-dessus code> Blocks . Il est fait afin de préciser ce que je fais.) P>
B code> implémente
C code>, vous pouvez lancer le
B code> objet sous forme de référence
C code> en ce moment, puis vous pouvez appeler les méthodes remplacées directement (sans réflexion). P>
A code> n'a pas de "no paramètre constructeur"? B>
Ajoutez simplement les paramètres requis à la classe B code>, comme
Public B (int extraparam, c) code> et appelez
super (extraparam) code> au lieu de < Code> super () code>. Lors de la création du
constructorb code>, ajoutez également le paramètre supplémentaire, comme
classb.getconstructor (INTEGER.TYPE, C.Class) code>. P>
s code> et chaîne
t code>? b>
t code> est utilisé par la classe anonyme directement. Lorsque
objetb.dosomething ("world"); code> est appelé,
"world" code> est le
s code> fourni à la classe
b code >. Étant donné que
Super code> ne peut pas être utilisé dans la classe anonyme (pour des raisons évidentes), tout le code qui utilise
Super code> est placé dans la classe
B code>. P>
Super code> plusieurs fois? B>
Il suffit d'écrire un modèle dans b.dosomething () code> comme ceci: p>
C code > Pour inclure
DOSOMODOASHTER1 () CODE> et
DOSOMODOASTER2 () CODE>. P>
p> packageb.b code> n'est pas compilée (puisque
main.java code> n'a pas toute référence à elle). Dans la deuxième exécution, la classe est explicitement compilée et vous obtenez ainsi le résultat que vous attendez. P>
NOCLASSDEFFUTRORROR CODE> Pendant le chargement d'une classe présente dans CompiléTime ClassPath, mais est absent dans la classe de classe d'exécution.
CLASSNOTFOUNDEXCEPTION CODE> Pendant le chargement d'une classe qui est absent dans la classe d'exécution, mais n'a pas besoin d'être présent dans Compilétime ClassPath.
@Ballusc Code>: Ma question dans Edit3 B> était liée à EDIT2 B>: Est quelque part spécifié que
NOCLASSDEffondError code> se produit, disons , pendant la construction de classe i> qui tente d'appeler une autre classe non existante ou ne se produit que lorsque la méthode i> qui appelle la classe non existante est appelée, ... plus général: où est spécifié quand b> une certaine classe est chargé? I>