posted 16 years ago
Consider the following code:
getMyData1 returns the type of the concrete implementation, while getMyData2 returns the type of the interface it implements.
The benefit of getMyData1 is that the calling code can do more things with it (all those methods of ArrayList that are not part of List). But there is a big drawback: by declaring the kind of List you're using as the return type, you've exposed it to all code that calls this method. If you later decide that using an ArrayList wasn't such a good choice after all -you'd much rather use a LinkedList-, well, you can't. Every piece of code that calls getMyData1 needs to be changed so that it no longer assumes it's getting an ArrayList.
You may not think that's a big deal if your own code is the only one calling getMyData1, but what if this was the public API of a library that other people use? You'd be out of luck.
If you had used getMyData2, you could have easily changed the type of myData from ArrayList to LinkedList, and noone would have been affected by that. It's rare that the calling method would need to it's getting an ArrayList anyway - just about all the interesting methods are part of List, so it's sufficient to declare that.