6
votes

Accès sur le terrain à Groovy pour Super Class

in Groovy Il y a un opérateur @ qui permet un accès direct sur le terrain. Cependant, on dirait que cela ne fonctionnera pas pour les champs déclarés en super classe. Considérez deux classes Java (non groovy): xxx

puis appelez l'accès direct à Groovy xxx

finit par avec exception: groovy.lang.missingfieldException: aucun champ de ce type: ID pour l'utilisateur de la classe

Lorsque j'essaie d'utiliser Access standard user.id = 1L Je reçois groovy.lang.readonlypropertyexception: impossible de définir une propriété en lecture-jour: ID pour l'utilisateur de la classe

est une option d'accès au champ déclaré en super classe? >


10 commentaires

Vous pouvez y accéder sans @ , pourquoi vous avez besoin d'un accès direct?


Je n'ai pas de setter pour id


Vous avez, car cela a été généré pour vous.


@JBaruch Java Classes


Alors qu'est-ce que user.id = 1l vous donne?


@tim_yates j'ai ajouté ce cas à ma question


Ah droite ouais sans piratage de réflexion, vous ne pouvez pas faire une propriété en lecture seule.


Cela fonctionne lorsque le champ est déclaré comme protégé


Si vous pouvez modifier la classe d'entité, vous devez créer un setter au lieu de s'appuyer sur la réflexion // accéder à un champ protégé.


J'ai sauté le cas d'utilisation que je pense était une erreur. Je ne veux pas exposer l'ID Ecrire un code de production - juste à la recherche de solution pour la définir dans des tests (SPOCK)


4 Réponses :


3
votes

Les champs privés ne sont pas accessibles à partir des cours d'enfants (ils ne sont pas hérités). Bien que Groovy vous permet d'accéder aux champs privés plus facilement que la réflexion Java, il ne peut toujours pas accéder aux champs qui n'existent pas.


4 commentaires

Comme je l'ai mentionné, ces classes sont Java et non groovy, donc pas de setter ici


Néanmoins, les champs privés ne sont pas hérités. Je voudrais refaire ma réponse, mais le message principal est le même: les champs privés ne sont pas hérités.


Je cherchais une certaine construction dans laquelle je pouvais dire directement que je m'intéresse directement à un domaine de Super Class: comme l'utilisateur. @ Super.id ou quelque chose comme ça. Équivalent de l'utilisateur.getclass (). GetsPlass (). GetDeclaredfield ()


seulement la réflexion, alors.



5
votes

Vous auriez probablement besoin de déclarer la propriété aussi protégée à la place:

class Entity {
  protected Long id;

  Long getId() {
    return id * 2;
  }
}

class User extends Entity {
}

User user = new User();
user.@id = 1L

assert user.@id == 1L
assert user.id == 2L


0 commentaires

5
votes

Vous pouvez accéder via une réflexion Java régulière, mais je ne sais pas comment rendre cela plus "groovy".

User user = new User()
fields = user.getClass().superclass.declaredFields
idField = fields[0]
idField.accessible = true
idField.set(user, 2L)
println idField.get(user)


1 commentaires

Oui, je suis surpris que je n'ai pas vu une solution plus "groovy" à cela. Décevant. Le mieux que je puisse faire est de supprimer des préfixes «set» et «obtenir» et des parens. VRAIMENT?!!!



0
votes

Permettez-moi de faire revivre cette question comme je traverse une chose la même récemment. Voici quelques pensées ...

Comme il est nécessaire que des tests peut-être une comparaison des égaux feraient au lieu de vérifier directement / régler les champs directement? P>

Modèle valant la peine d'être envisagé si l'alternative est la désencapsulation. Je veux dire, s'il n'est pas nécessaire de toucher ces champs dans le code Prod, il n'aurait pas besoin d'être touché dans des tests non plus. P>

entité code> aurait ses propres champs basés sur Equals code> et hashcode code> implémenté. @equalSandHashCode de Lombok Code> L'annotation peut aider à réduire la chaudière. P>

test va alors comme attendre: nouvelle entité (ID) == Nouvelle entité (ID) CODE> (En supposant qu'il y ait un tel constructeur). p>

Si l'égalité n'est pas la voie à suivre la portée de l'emballage peut donner une meilleure encapsulation avec une structure de paquet appropriée (principale / src / java): P>

package foo.bar

class EntityAccess {
    private final Entity entity

    EntityAccess(Entity entity) {
        this.entity = entity
    }

    static EntityAccess access(Entity entity) {
        new EntityAccess(entity)
    }

    Long getId() {
        entity.id
    }

    void setId(Long id) {
        entity.id = id
    }
}


0 commentaires