This is an application of the famous principle of "coding to an interface, not an implementation". Essentially, the idea is that you should use a reference type that's as high up the class hierarchy (i.e. more abstract) as possible for any given task, so that you don't tie yourself down needlessly to a more specific class than necessary. Among other things, this helps to promote loose coupling, and also makes your code more amenable to future change.
For example, suppose that in the future someone in your team comes up with a new and amazingly efficient list class (let's call it CoolList). If your reference variables and method parameters have all along been tied specifically to ArrayList, then you'll have to go back and change every one of those reference types to CoolList. If these uses of ArrayList include interfaces that you expose to other developers, then you also risk breaking other people's code--a consideration that in some cases might completely prevent you from switching to CoolList. In contrast, if you've been using the abstract List interface all along, then you only have to change a handful of "new ArrayList()" instantiations to "new CoolList()", and you won't have to modify any of your own exposed interfaces.
There's a lot more to say on this topic, but hopefully the above gives you a glimpse of why this is generally a very valuable principle.
I’ve looked at a lot of different solutions, and in my humble opinion Aspose is the way to go. Here’s the link: http://aspose.com