views:

115

answers:

3

Given a method that accepts as a parameter a certain supertype. Is there any way, within that method, to determine the actual class of the object that was passed to it? I.e. if a subtype of the allowable parameter was actually passed, is there a way to find out which type it is? If this isn't possible can someone explain why not (from a language design perspective)? Thanks

Update: just to make sure I was clear

Context: MySubType extends MyType

void doSomething(MyType myType) {
  //determine if myType is MyType OR one of its subclasses
  //i.e. if MySubType is passed as a parameter, I know that it can be explicitly
  //cast to a MySubType, but how can I ascertain that its this type
  //considering that there could be many subclasses of MyType
}

Since the method signature specifies the parameter as being MyType, then how can one tell if the object is actually a subtype of MyType (and which one).

+5  A: 

If you look at the javadoc for the Object class, you will find that every object supports getClass(). That's the Class of the object, and you can go from there.

If the object is MyType then getClass() == MyType.class'. If the object is a superclass, thengetClass() != MyType.class`.

There are only these possibilities. If the type of the param is MyType, and MyType is a class and not an interface, then either the object is MyClass or it's a subtype. If it's a subtype, then getClass() is returning the Class for the subtype. You can use the API of Class to explore it.

You can, of course, use reflection to explore the type hierarchy. You can ask MyType.class for a list of its direct subclasses, and recurse from there, and have a fine old time. But you don't need to.

bmargulies
I don't think this is what I meant..
lkm
@lkm -- See edit.
bmargulies
what if the object is a subclass? then getClass() == MyType.class, BUT how can I find out that getClass()==MySubType.class?
lkm
bmargulies's answer is right, that allows you know if the object is of type MyType; if it's not, then it must be one subclass - it's difficult to understand what more do you need.
leonbloy
Ok - if its not MyType then it must be a subclass - I agree with that. I am wondering how to figure out WHICH subclass it is? All the other answers so far suggest using instanceof (or something similar). But I am wondering why you have to explicitly test for this. Why can't there be an operation that tells you that MyType is this or that subclass? Hopefully I'm clear..this is just kind of hard to articulate.
lkm
The result of getClass() *is* the subclass. Its a Class object that represents the class.
bmargulies
But getClass() tells you that: WHICH subclass it is. It tells you that at runtime, granted. It seem that you are thinking in something like taking into acount in your code "all the possible subclasses", specifically and individually - but you obviously cannot "know" all the possible subclasses at compile time, anyone can create its own subclass class and call your method with an instance of that class.
leonbloy
thanks leonbloy, what you said makes sense. i got really mixed up for a while. I think I have it straight now thanks to your explanation.
lkm
+1  A: 

Yes there is -- there's a built in reflection API called Trail that allows you to examine the types of any instance of a class. The method getClass() that is inherited from the Object class will give you a Class object that you can examine. A good starting point is the Trail tutorial from Sun.

haldean
Pretty sure that Trail is just Sun's old name for tutorials. This is generally known as the reflection API :-p
Steven Schlansker
Well that's thoroughly embarrassing (:
haldean
+1  A: 

I assume that MyType is the superclass type, right?

1/ If you just want to know that it does not belong to your super class type: you can check

if (m.getClass() != MyType.getClass())

2/ If you want to check if m belongs to a certain subclass, I don't think there is a way, you have to hard code it like

if (m.getClass() == MySubType) {
}

or you can use:

if (!(m instanceof MySubType)) {
}
vodkhang
Exactly, this is what I assumed. But I am wondering why this is? I konw that the type passed to the method can be determined at runtime, but why isn't there an easy common way to do this (without reflection)? Is there usually no need for this feature?
lkm
yeah, because usally, when you pass as a supertype, you want polymorphism, which means that you want to treat all of the parameter object as the same one. So, it will not be good in terms of OOP if you have to treat every subtype differently, which make polymorphism useless. I don't know what you need to do, but I think that you can create another interface type to abstract all of the subclass type you need to if else
vodkhang
i think instanceof is just what you need.if (object instanceof MyType) means: is this object instance of MyType or any of MyType's subclasses
deadsven