6
votes

Comment pouvons-nous ajouter une classe transitoire à la classe existante à l'aide de la réflexion en Java?

Y a-t-il un moyen de rendre le champ statique ou transitoire à l'aide de l'API de réflexion Java.

EDIT: J'ai des haricots qui sont déjà sérialisés à l'aide d'API SOAP et sont utilisés par certains clients, pour certains clients, je ne veux pas exposer un ou deux champs.

Bien sûr, il y a tellement de façons de le faire sans changer ni ajouter de mot-clé transitoire.

veux juste savoir si cela peut être fait, et si oui, comment?

edit: Je ne l'appellerais pas une API ou un problème de cadre, plus comme une faille de conception ... J'utilise Apache Axis2 pour SOAP


4 commentaires

Pourriez-vous spécifier votre besoin? Cela ressemble à une "solution avant le problème" question.


Eh bien, votre commentaire ressemble plus à un critique au lieu d'aider


Désolé si vous y réfléchissez de cette façon ... c'est parce que la plupart du temps, les gens demandent un moyen de mettre en œuvre une solution qu'ils imaginent pour leur problème au lieu d'indiquer le problème lui-même.


Bien que cela puisse sembler utile de répondre à la question, cela ne l'est souvent pas. Si nous vous envoyons mal au mauvais chemin et vous aidez à introduire un piratage dans votre application qui va réellement le rendre plus difficile à maintenir, nous n'avons pas aidé un peu. :)


4 Réponses :


5
votes

non. Une telle chose nécessiterait de modifier le code octet de la classe. Une difficulté particulière dans le cas des champs statiques est qu'ils sont accessibles à l'aide de différents bytecodes que les champs d'objets.

Je ne vois pas de pourquoi un champ ne pouvait pas être fait transitoire en runtime, au moins en théorie, mais l'API de réflexion actuelle ne le permet pas. Voir aussi: La propriété transitoire d'un champ peut-elle / Soyez défini par la réflexion dans Java?


0 commentaires

1
votes

Vous ne pouvez pas le faire avec l'API de réflexion. Je pense qu'il y a quelques outils de manipulation de code d'octet, mais dans ce cas, vous pouvez utiliser le décorateur motif. Cela résout le problème, mais je pense que c'est extrêmement moche:

(j'ai omi la chaudière habituelle d'ici comme des interfaces) xxx i Utilisé objet pour le type de la classe que vous allez envelopper mais, bien sûr, vous pouvez remplacer tout type de votre choix. Utilisation d'une approche comme celle-ci, vous pouvez "décorer" n'importe quelle classe avec un champ statique.

Si vous êtes vraiment, extrêmement doit veut un champ statique dans un objet à l'heure d'exécution. vous aider, mais je pense qu'il y a un défaut de conception se cache quelque part.


2 commentaires

Pouvez-vous le clarifier plus loin? Quels cadres utilisez-vous? Cela ressemble plus à un problème de cadre.


Édité à nouveau, laissez-moi savoir si vous souhaitez commenter cela.



1
votes

Vous pouvez envelopper votre haricot à l'intérieur d'un autre haricot qui expose uniquement les champs que vous souhaitez exposer dans votre API. Par exemple, avec un haricot interne avec les champs foo code>, bar code> et baz code>, où vous ne voulez pas exposer baz .

délégation de Lombok peut rendre cette incroyablement simple, Mais voici un exemple en utilisant un java plain-old-java. p> xxx pré>

réponse originale, concernant les modificateurs de réglage strong> p>

Vous ne pouvez pas définir modificateurs. Vous pouvez les vérifier, cependant. P>

public class FieldModifierDecorator extends Field {
    protected Field field;
    private int modifiers = -1;

    public static void decorate(Field field) {
        FieldModifierDecorator newInstance = new FieldModifierDecorator();
        newInstance.field = field;
        return newInstance;
    }

    public void overrideModifiers(int modifiers) {
        this.modifiers = modifiers;
    }

    public int getModifiers() {
        if (-1 == modifiers) {
            return field.getModifiers();
        }
        return modifiers;
    }
}

// Example usage
public Field makeFieldAppearTransient(Field field) {
    FieldModifierDecorator decoratedField = FieldModifierDecorator.decorate(field);
    decoratedField.overrideModifiers(field.getModifiers() | Modifier.TRANSIENT);

    // if (Modifier.isTransient(decoratedField.getModifiers())) {
    //     System.out.println("It looks transient, but really isn't.");
    //}

    return decoratedField;
}


0 commentaires

0
votes

Modification des informations de classe ou une modification du code octet est définitivement le mauvais outil pour le travail. Vous essayez de résoudre un problème commercial avec des outils techniques uniquement.

Cela semble plus comme si vous avez besoin d'un concept de permission. Les utilisateurs peuvent avoir la permission de voir des champs. Sur la base de celle-ci, vous pouvez utiliser l'introspection Java Bean pour effacer les valeurs de ces champs juste avant qu'ils ne soient envoyés au client.

Cependant, cela pourrait avoir ses problèmes aussi. Un client doit pouvoir déterminer s'il a la permission de voir ce champ ou non.


0 commentaires