Lets say I right a class called “piece” and I include a toString() method within it.
Now, there are two ways I might called that method:
(1)
piece p = new Piece()
p.toString();
(2)
object o = someMethod() //this returns a type object
(piece)o.toString();
My question is this: Is there a way for the piece.toString() method to recoginize if it was called via a cast (case 2) or via a direct instance variable (case 1)?
This isn’t a direct answer to your question, but for case 2, why wouldn’t you just have someMethod() return an object of type piece, rather than a generic Object which you then recast?
Well, as a clumsy hack you could rewrite the second example as
Object o = someMethod();
String s = o.toString();
s += ((piece)o).toString();
…of course, this won’t work if you’ve got piece.toString() printing directly as your example implies, rather than returning a String which contains the data you want.
Regardless, I’m pretty sure that there’s no elegant way to get the information that you want (short of writing a myToString() method which takes its own calling object as an argument and does the detection with instanceof, then returns whatever you’re looking for. This won’t allow you to use the assorted System.out.print functions directly, but such is life).
The big question, though, is “why do you care?” Whatever information you’re trying to infer, there’s probably an easier way to get at it.
Okay, I’ll explain the background…boring and dry as it is.
I have a collection class that contains a linked list of piece types. The linked list itself is comprised of node types, which contain a data field of type object and a nextNode field of type node. The nextNode field points to the next node, whilst data points to the data to be stored (a piece type, of course).
So, when I call collection.toString() it simply iterates through the linked list, calling toString on each piece…this is where the cast is required:
((Piece)node.getData()).toString();
The getData() returns the data, as on object, referenced by the node. I cast this to a piece type so I can invoke .toString() on it.
As odd as it seems, I want piece.toString() to have a different output if it is called via the above cast, vs. if its called “directly”.
Since you’re already having to do the cast “by hand,” you may as well just make it:
((Piece)node.getData()).castedToString();
It’s not terribly elegant, since it involves an extra method, but it’ll solve your problem.
I’ve been told that there are OO languages in which the route by which a method is called is available (like a parameter) to the methods themselves, but I’ll be damned if I could name one of those languages now, and as far as I know, Java isn’t one of them.
When you stored it into your collection I assume it was Piece? When you retrieve it from the collection, I don’t see why you have to cast it from Object to Piece, since Object provides toString(). So just retrieve it and call toString(), and the Piece version of toString will be invoked.