Skip to content
Advertisement

Casting an Object into a Class of type T

Let’s say I have an empty class called ClsA(), and a subclass of it called ClsB() like so:

JavaScript

Supposing that we now have an ArrayList of ClsA type objects, I want to be able to count how many elements in the ArrayList are actually of type ClsA or ClsB. Based on some searching, I found out that the following function works wonders:

JavaScript

Indeed, the following sample main method does give the correct output.

JavaScript

However, let’s say that ClsB is now defined as followed:

JavaScript

I now want to count how many ClsB instances of a specific type are present in the given ArrayList. After checking in my countInstances() that an element is of the given class (in this example ClsB), I want to be able to also check if the type given to the method matches the type of the element. Is there any way to actually cast Object o into an instance of the given class since the compiler doesn’t really know its actual type?

So far I’ve gotten to this point:

JavaScript

Advertisement

Answer

Yes, there is cls.cast(o); which will do it, and will give you a T (because the type of cls is Class<T>, and the cast(Object o) method of j.l.Class is defined to return T. It acts just like the cast operator would, in that it does nothing: It just asserts that o is in fact an instance of this class (so, created as new This() or new SomeSubtypeOfThis()). If it is, it does nothing. If it is not, it throws ClassCastException. No conversion occurs in any case.

This isn’t useful; after all, T is still just object. This will not give you the power to call getType() on your o – because T has no bounds, T is not going to have any methods other than what java.lang.Object already has.

In general, what you’re engaging in is structural typing: It doesn’t matter what ClsB is, it just matters that it has a method named getType.

This is very bad.

It means that the one method of public interface Camera { public void shoot(Person p); } and public interface Gun { public void shoot(Person p); } are, to such a system, interchangible, and thus you will blow somebody’s head off by accident.

Types (classes, interfaces, etc) are exempt from this problem because they have a namespace – a package header, which serves to make them effectively unique. A method should therefore never be considered as meaning anything whatsoever, unless that method is in context of the type it in.

Thus, what you COULD do, is something like this:

JavaScript

The above would return ‘2’ for a list with one instance of ClsA and one instance of ClsB, and you pass ClsA.class as second param.

After all, an instance of ClsB is also an instance of ClsA.

If you’re looking for an answer of ‘1’, you’re looking for:

JavaScript

Then for your ‘getType’ method, we must link that method to an actual type, because otherwise you’re shooting people in the face and that’s bad. So, I put the getType() method in ClsA, and then we demand that you pass a list of things which are ClsA’s:

JavaScript

Note that this method can be invoked with an ArrayList<ClsA> or an ArrayList<ClsB> – either is fine. <? extends ClsA> makes that possible; the ? extends is important. Without it, new ArrayList<ClsB>() could not be passed as first parameter.

If you want to combine these two ideas, That’s.. a bizarre mix of concerns and sounds like you’re engaging in the concept of structural typing in java, or otherwise some hacky attempt to make dynamic typing happen. Stop doing that; java is not that kind of language, and it will hurt the whole time, and the end result will be non-idiomatic, hard to maintain, and hard to read code. Find a java-esque way to do whatever you are doing. However, and don’t say I didn’t warn you:

JavaScript

There is no point trying to generalize ClsA here, because by doing so you remove the ability for your code to be capable of realizing that ClsA instances have a getType() method.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement