2009-05-07 6 views
1

Cela fait un de ces jours que quelqu'un peut m'aider avec cela.Java Reflection est égal à Question

J'ai 2 objets Stock dont je veux comparer les propriétés à l'exécution. Une instance est l'instance mise en cache, l'autre est une nouvelle instance stock qui vient d'être livrée à mon système, qui peut ou non être égale à l'instance mise en cache. Voir ci-dessous où m est une méthode de la Bourse de classe et le stock est une instance de Stock

try { 

// I want to compare these two objects, return type of m may vary 
Object result = m.invoke(stock); 
Object cacheResult = m.invoke(stockCache.get(ticker)); 

// The return type of m may vary but is known at runtime 
Class returnType = m.getReturnType(); 

// I assume I need to cast before .equals() will work correctly 
if(result.equals(cacheResult)) { 
    // Will this work or do I need to cast 
} 

    }catch (Exception ex) { 
} 

EDIT: Pour ceux qui ont demandé pourquoi je me sers de réflexion, je suis en utilisant le cadre ajax inverse DWR et je suis essayer de mapper une propriété html id à mes propriétés d'objet, ce qui me permet d'annoter mes propriétés avec leur valeur d'identifiant HTML associée. En poussant l'objet sur l'interface utilisateur, cette méthode me permet de ne pousser que les propriétés qui ont changé et non l'objet entier.

+1

Pourriez-vous nous donner plus d'informations sur les types de rendement attendu de m? S'agit-il de valeurs scalaires telles que les chaînes ou les entiers, ou s'agit-il d'objets plus compliqués? Sont-ils des objets avec une superclasse commune? –

+0

Vous n'avez pas besoin de diffuser. Et vous n'avez pas non plus besoin du try/catch (Exception). Vous avez juste besoin de vous assurer que votre méthode égale fonctionne comme supposé. – OscarRyz

Répondre

7

Vous ne devriez pas avoir besoin de lancer. Java choisira automatiquement la bonne méthode equals. Je vous recommande de déboguer cette ligne pour voir ce que Class chaque objet est.

+2

Ce n'est pas "ne devrait pas avoir besoin de lancer", vous n'avez pas besoin de lancer. Java va déterminer et appeler la méthode equals correcte (Object) lors de l'exécution. –

+0

@Steve: J'ai gardé mes mots ouverts à la possibilité (bien que jamais si petite) que Karl puisse fonctionner sur une JVM obscure et boguée. Certes, la possibilité est suffisamment petite que j'aurais dû utiliser le libellé plus fort. Merci pour votre correction. :) –

3

Non, vous n'avez pas besoin de lancer. Normalement, équivaut à la méthode ressemble

@Override 
public boolean equals(Object o){ 

    if (! o instance of ThisClass){ 
     return false; 
    } 

    //other equality tests based on members 
} 

Si votre cache ne contient qu'un seul des objets de classe (i.e. pas la mise en cache des classes dérivées), il devrait fonctionner. On dirait que vous stockez des objets dans votre StockCache. Peut-être que c'est un peu trop générique, et rétrécir à une classe de base (peut-être StockClass) serait une meilleure option. Ensuite, votre getter serait, défini dans votre classe de cache serait:

StockObject getStockObject(KeyType key); 

En plus de cela, la réflexion semble comme un surpuissant (si vous avez alredy les objets que vous souhaitez comparer, pourquoi la réflexion de l'utilisation?)

+3

Bien qu'il s'agisse d'une erreur extrêmement courante, il est techniquement incorrect d'utiliser la comparaison instanceof dans un remplacement equals(). Utilisez x.getClass() == y.getClass() à la place. L'utilisation de instanceof renvoie true pour les sous-classes, ce qui peut violer la propriété symétrique de la méthode d'égalité. Vous pouvez également combiner la vérification de null et une vérification de référence automatique en une ligne en utilisant if (this == o) ... – sooniln

+1

Soonil: Les collections utilisent instanceof. Vous devez comprendre ce que vous faites. Ou juste rendre la classe finale. –

+0

Tom: Un @Override serait utile là-bas. Comme l'interrogateur demande à propos de casting, peut-être qu'ils surchargé au lieu de surcharger la méthode. En outre, pas besoin de vérifier null avec instanceof. –

2

Le moulage n'aura aucun effet ici. Le résultat dépend entièrement de la façon dont la méthode equals() est implémentée dans la classe Stock.

Mais pourquoi utilisez-vous la réflexion pour cela? Ce n'est probablement pas la bonne chose à faire.

+0

On dirait que equals est appelé sur la valeur de retour de Stock.m() plutôt que Stock lui-même. –

+0

Pour ceux qui m'ont demandé pourquoi j'utilise la réflexion, j'utilise le DWR reverse framework ajax et j'essaye de mapper une propriété html id à mes propriétés d'objet, ce qui me permet d'annoter mes propriétés avec leur valeur d'ID HTML associée. En poussant l'objet sur l'interface utilisateur, cette méthode me permet de ne pousser que les propriétés qui ont changé et non l'objet entier. – Karl