If the component type of the List does match the expected type, there is no problem.
Up vote 0 down vote favorite share g+ share fb share tw.
I'm refatoring a home-grown DAO container, hoping to make the class generic. It internally uses an ArrayList to store the retrieved objects. One usage of this class puts the container's list into a request scope, and due to a limitation of Websphere, I can't pass the generic List to the request scope (Websphere doesn't handle generics out-of-the-box) If I go ahead with my refactorings, I will need to convert/cast the List into a non-generic List object.. // Boils down to this... List listFoo = new FooListing().findAllFoo(); List listThings = listFoo; request.
SetAttribute("listThings", listThings); What are the implications of reversing a generification like this? Should I avoid doing this kind of manipulation? EDIT: The code snippet is verbose to explicitly demonstrate what I'm describing.. java generics arraylist generic-list link|improve this question edited Mar 11 '10 at 22:06 asked Mar 11 '10 at 6:11brass-kazoo2,07661938 81% accept rate.
You don't need the intermediate assignment to listThings; you can just set listFoo directly into the request. – Software Monkey Mar 11 '10 at 6:44.
If the component type of the List does match the expected type, there is no problem. Generics in Java are only used for type-checks by the compiler, they have not effect at runtime. If you are using an older library that does not support generics, you have no choice but to ignore the generic type.
Things should continue to work, as this system has been designed with backwards compatibility in mind. So all you are losing is the compile-time type checking (it puts you back to where Java was at 1.4, which means, if the types match, everything will work, if not, you'll get ClassCastExceptions or other unwanted behaviour at runtime). However, I think you can just write request.
SetAttribute("listThings", listFoo); This method takes any kind of Object. Even if it wanted a List, you could still pass a List (which is still a List).
Cool, just wanted to explicitly demonstrate what I was describing in the code example – brass-kazoo Mar 11 '10 at 6:21 You can pass your List to every method that wants a non-generic List. WebSphere cannot interfere with that. This is how the backwards-compatibility works.
– Thilo Mar 11 '10 at 6:25.
Java uses "type erasure" for generics -- essentially that means that the compiler checks the generics, but the runtime forgets all about it and just treats it as a list of objects. * Whenever you treat a List as just a List, you won't get compiler checks to make sure you don't put a Bla into your list. So you could get a ClassCastException if you call List.get() and it turns out to be a Bla hiding in the list.
But that can only happen if you some code puts a Bla in your list. If you wan't to be cautious, then if you pass the List as a List to anything that might add a non-Foo to the list, don't treat it as a List whenever you access it, but treat it as a list of Objects and add instanceof checks. *Some of the information is accessible at runtime, but let's not complicate matters.
Luckily, the usage of the list in this case is only for display purposes, so there's no risk of bla exploding in our faces – brass-kazoo Mar 11 '10 at 6:31.
A "non-generic" version of a generic type is called a "raw type". Passing a generic type where the raw equivalent is requested is generally ok. This is actually the main reason generics in Java work the way they do (with erasure): to enable interoperability between "generified" code and pre-generics code.
The main thing you need to be careful about is that if you pass a List to something that askes for a List, they may put non-Foo objects into the List. You won't get any compile time checking to help you here. You do get some runtime checks: a ClassCastException will be thrown when you use a method that returns a Foo on your List and it has to return a non-Foo.
If you want more fail-fast behavior you can wrap your List with Collections.checkedList() to get a List that'll check the type of elements on insertion. Things get more complicated if Foo itself is a generic type. Runtime checks are only done on reified types (ie: the type with generic type parameters removed) so if you give them a List> and they insert a Set or just a Set, you won't know since the runtime/reified type of the element is Set either way.
First, you can't cast a generic to a non-generic list so yeah you'd have to convert it. Second, the two main advantages to a generic list are 1) it ensures that all objects are of the specified type and 2) it allows you to directly access methods of the object collection without needing to recast them. This allows you to write cleaner code and saves some processing cycles from having to cast back and fourth.
Neither one of these advantages is a dire need however. If you can't use them you won't notice a difference in performance. Your code may look a little messier though.
1 You absolutely can cast a generic to a non-generic list. You may have to suppress the warning, but you absolutely can do it. Which makes sense since they're exactly the same type after erasure.
– polygenelubricants Mar 11 '10 at 6:22 "you can't cast a generic to a non-generic list". You can write List x = (List) listFoo. – Thilo Mar 11 '10 at 6:23 Ah my bad.
I must have been thinking "you can't cast one generic list to another generic list" and gotten it mixed up in my head. – Spencer Ruport Mar 11 '10 at 6:26.
I have similar problems with Weblogic Portal. Just use none-generic type for this case.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.