9
votes

Accès aux champs de classe sans utiliser de réflexion?

Y a-t-il un moyen d'accéder à un champ code> spécifique code> sur une classe sans utiliser de réflexion?

Considérez cette classe: P>

Field f = MyType.class::theNumber;


1 commentaires

J'essaie de sentir tes arrière-plan, votre motivation (?) À remettre en question. J'essaie de résoudre une idée similaire (ou inverse) Stackoverflow.com / Questions / 32284675 / ... Désolé pour "La publicité cachée" :)


4 Réponses :


2
votes

question intéressante. Non, il n'y a aucun moyen de le faire sans utiliser java.lang.reflect , mais donné la classe intégrée pseudo-propriété sur des classes, je peux voir pourquoi vous Demandez.


1 commentaires

Pensé donc. En ce moment, j'utilise une énumération avec des valeurs par rapport aux noms de champ égaux dans la classe. J'espère se débarrasser de cela puisque chaque nom de terrain est répété dans l'énum.



-1
votes

Non, ce n'est pas ... mais vous pouvez y parvenir avec une interface et une fermeture xxx


5 commentaires

Cela n'accède pas au champ , il accède à la valeur du champ sur une instance donnée.


Compris ... mais je suppose qu'il ne veut que le champ afin qu'il puisse accéder aux valeurs plus tard


Eh bien, pour faire cela, tout simplement mytypeinstance.thenumber semble la manière la plus directe, si vous connaissez le nom du champ à la compilée.


Il connaît le terrain au moment de la compilation ... mais parfois d'écrire un code générique, vous avez besoin de constructions comme celle-ci. Voyons voir ce que @geir dit


Comme indiqué ci-dessus, je connais le champ à la compilation. J'essaie d'écrire un constructeur SQL générique qui est sûr de sécurité lorsque vous référencez des noms de colonne de table, et ne nécessite pas non plus de duplication des noms de colonnes (par exemple les définissant dans une énumération). Exemple db.select (mytype :: thinyumber) .from (...) . @Truthslie et @ Jacek-CZ semblent avoir fourni des indices précieux que je suivrai!



0
votes

Métamodel JPA2 (utilisé dans les requêtes Typeafe "par critère") a un concept similaire.

MyType_.theNumber


0 commentaires

3
votes

Vous pouvez étendre le compilateur Java avec des processeurs d'annotation. Ces processeurs sont un moyen de numériser votre code source pendant la compilation. Ils ont été introduits avec des annotations mais ils sont capables de numériser l'ensemble du code source non seulement des annotations.

Avec le code source numérisé, vous pouvez générer des classes d'accesseur à n'importe quelle classe que vous compilez. De cette façon, vous pouvez éliminer la réflexion.

Si vous voulez seulement obtenir des erreurs pendant que vous écrivez le code dans votre IDE, vous pouvez utiliser Javax.annotation.Processing.processingenvironment.getMessager (). PrintMessage () (voir aussi javax.tools.diagnosticlistener) pour générer des erreurs le IDE peut montrer.

donc l'idée de base est:

  1. Écrivez un processeur d'annotation qui analyse le code source que vous souhaitez refléter
  2. extraire le champ que vous souhaitez avoir accès à via javax.lang.model.Element.Element.ElementVisitor

    Si vous souhaitez générer de type, économisez un accès au champ:

    3.1. Générez une source qui accédera à ce code source

    Si vous souhaitez vous assurer qu'un appel réfléchissant à un champ est valide:

    3.2. Soulevez une erreur via Traitecenvironment.getmessager (). PrintMessage ()

    Bien sûr, vous devez écrire le code pour vérifier les appels réfléchissants ou générer les accesseurs.

    Et les informations que vous souhaitez obtenir doivent être extractibles depuis le code Sourcecode car toute la magie se produit pendant la compilation et non au runtime


1 commentaires

Wow, j'ai appris quelque chose de nouveau là-bas, je ne connaissais pas les transformateurs d'annotation. Je vais certainement vérifier cela!