Vous pouvez maintenant charger des classes dans l'article précédent "Supporting Object Creation". Je voudrais profiter d'une classe qui peut être chargée et gérer les appels de méthode statique pour cette classe.
Confirmez que vous souhaitez prendre en charge les appels de méthode statiques.
Par exemple, il existe le programme suivant.
La première ligne charge la classe ʻInteger dans la variable ʻintegerClass
.
Je veux appeler la méthode statique toHexString
de cette classe sur la deuxième ligne et afficher sa valeur de retour.
La méthode statique toHexString
renvoie l'entier d'argument sous forme de chaîne hexadécimale.
L'exemple d'argument est «255», donc la sortie sera «ff».
var integerClass = loadClass("java.lang.Integer")
println(integerClass.toHexString(255))
Réfléchissons à la façon de l'implémenter dans Interpreter. Il n'y a aucun changement dans l'analyse des phrases (Lexer) et l'analyse syntaxique (Parser).
Dans l'article précédent, "Appels de méthode de support", les appels de méthode d'instance étaient pris en charge. La syntaxe de la méthode statique étant la même que celle de la méthode d'instance, la partie correspondante est la même que celle de la méthode d'instance.
Pour l'implémenter, reportez-vous au type de «v» lorsqu'il y a un appel de méthode tel que «v.method ()». Il sépare s'il s'agit d'un appel de méthode d'instance ou d'un appel de méthode statique. Si le type de «v» est «Classe <?>», Il est considéré comme un appel de méthode statique. Tout autre type est considéré comme un appel de méthode d'instance. D'autres types sont, par exemple, «String» et «Integer».
Passez à la mise en œuvre. Jetons un coup d'œil aux modifications apportées à l'interpréteur.
Interpreter.java
Une implémentation d'Interpreter.java.
Ceci est une modification de la méthode func ()
.
La méthode func ()
garantit que l'argument value
est appelable comme une fonction.
Changé pour mettre l'instruction ʻif sous
// Update. Le «v» dans l'exemple précédent »v.method ()« est »d.left». Obtenez le type de
v avec
d.left.getClass (). Si le type de
v est
Classe <?>, Il est considéré comme un appel de méthode statique, sinon il est considéré comme un appel de méthode d'instance. L'instruction ʻif
détermine ce qu'il faut attribuer au champ mf
de la variable de type MethodFunc
.
Si vous pouvez préparer correctement les valeurs pour le champ mf
, vous ne serez pas conscient de la différence entre les appels de méthode statique et les appels de méthode d'instance.
C'est parce que l'appel de méthode peut être exécuté par la méthode ʻinvoke de la classe
MethodFunc`.
Si l'instruction ʻifest vraie, c'est-à-dire un appel de méthode statique, alors
d.left lui-même est assigné à
mf.class_. C'est parce que «d.left» lui-même représente le type.
null est assigné à
mf.target. L'affectation de «null» est due au fait qu'il s'agit d'un appel de méthode statique et ne nécessite pas qu'une instance appelle la méthode. Si l'instruction ʻif
est fausse, c'est-à-dire un appel de méthode d'instance, elle reste la même que celle implémentée dans l'appel de méthode précédent.
Interpreter.java
public Func func(Object value) throws Exception {
if (value instanceof Func) {
return (Func) value;
} else if (value instanceof Dotted) {
Dotted d = (Dotted) value;
MethodFunc mf = new MethodFunc();
mf.name = d.right.value;
// Update
Class<?> c = d.left.getClass();
if (c == Class.class.getClass()) {
mf.class_ = (Class<?>) d.left;
mf.target = null;
} else {
mf.class_ = c;
mf.target = d.left;
}
return mf;
} else if (value instanceof Variable) {
Variable v = (Variable) value;
return func(v.value);
} else {
throw new Exception("Not a function");
}
}
C'est tout pour les principaux changements.
Le programme ci-dessous utilisant l'implémentation ci-dessus
var integerClass = loadClass("java.lang.Integer")
println(integerClass.toHexString(255))
Pour afficher la représentation hexadécimale «ff» de «255».
Interpreter.java
public static void main(String[] args) throws Exception {
String text = "";
text += "var integerClass = loadClass(\"java.lang.Integer\")";
text += "println(integerClass.toHexString(255))";
List<Token> tokens = new Lexer().init(text).tokenize();
List<Token> blk = new Parser().init(tokens).block();
new Interpreter().init(blk).run();
// --> ff
}
C'est tout pour la mise en œuvre. Merci beaucoup.
La source complète est disponible ici.
Calc https://github.com/quwahara/Calc/tree/article-20-static-method-invocation/Calc/src/main/java
Il y a un article de suite.
** Chargez le script à partir d'un fichier et exécutez-le ** http://qiita.com/quwahara/items/bac43cd1df11b025e46a
Recommended Posts