views:

907

answers:

3

Hi Guys,

Its been one of those days can someone help me out with this.

I have 2 Stock Objects which I want to compare properties of at runtime. One instance is the cached instance, the other is a new stock instance which has just been delivered to my system, which may or may not equal the cached instance. See below where m is a method from the class Stock and stock is an instance of 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: For those who have asked about why I am using reflection, I am using the reverse ajax framework DWR and I am trying to map a html id property to my object properties, allowing me to annotate my properties with their associated HTML id value. When pushing the object to the UI this method will allow me to only push properties that have changed and not the whole object.

+7  A: 

You shouldn't need to cast. Java will automatically choose the correct equals method. I recommend you debug that line to see what Class each object is.

Adam Paynter
It's not "shouldn't need to cast", you don't need to cast. Java will determine and call the correct equals(Object) method at runtime.
Steve Kuo
@Steve: I kept my wording open to the possibility (albeit ever so small) that Karl could be running on some obscure, buggy JVM. Granted, the possibility is sufficiently small that I should have used the stronger wording. Thank you for your correction. :)
Adam Paynter
+3  A: 

No, you dont need to cast. Normally, equals method looks like

@Override
public boolean equals(Object o){

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

   //other equality tests based on members
 }

If your cache holds only one class-objects (i.e not caching derived classes), it should work. Looks like that you are storing Objects in your StockCache. Maybe that's a little too generic, and narrowing down to some base class (maybe StockClass) would be a better option. Then, your getter would be, defined in your cache class would be:

StockObject getStockObject(KeyType key);

In addition to this, reflection seems like an overkill (if you alredy have the objects you want to compare, why use reflection?)

Tom
While it is an extremely common mistake, it is technically incorrect to use the instanceof comparison in an equals() override. Use x.getClass() == y.getClass() instead. Using instanceof returns true for subclasses, which can violate the symmetric property of the equality method.You can also combine the null check and a self reference check in one line using if(this == o) ...
Soonil
Soonil: Collections use instanceof. You need to understand what you are doing. Or just make the class final.
Tom Hawtin - tackline
Tom: An @Override would be useful there. As the questioner is asking about casting, perhaps they overloaded instead of overridden the method. Also, no need for null check with instanceof.
Tom Hawtin - tackline
Tom H. : ahh yes, @Override. Editing. Thanks
Tom
+2  A: 

Casting will not have any effect here. The result depends entirely on how the equals() method is implemented in the Stock class.

But why are you using reflection for this anyway? It's most likely not the right thing to do.

Michael Borgwardt
It looks like equals is being called on the return value of Stock.m() rather than Stock itself.
Matthew Murdoch
For those who have asked about why I am using reflection, I am using the reverse ajax framework DWR and I am trying to map a html id property to my object properties, allowing me to annotate my properties with their associated HTML id value. When pushing the object to the UI this method will allow me to only push properties that have changed and not the whole object.
Karl