Occasionally I see somebody create an arraylist like this, why?
List numbers = new ArrayList( );
Instead of:
ArrayList<something> numbers = new ArrayList<somethi开发者_运维技巧ng>();
If you asking about using interface instead of concrete object, than it is a good practice. Imagine, you will switch to LinkedList
tomorrow. In first case you won't need to fix variable declaration.
If the question was about non-using generics, then it is bad. Generics are always good as they give type safety.
What's good: 1. List is a general case for many implementations.
List trololo = new ListImpl();
Hides real implementation for the user:
public List giveMeTheList(){ List trololo = new SomeCoolListImpl(); return trololo; }
By design it's good: user shouldn't pay attention to the realization. He just gets interface access for the implementation. Implementation should already has all neccessary properties: be fast for appending, be fast for inserting or be unmodifiable, e.t.c.
What's bad: I've read that all raw types will be restricted in future Java versions, so such code better write this way:
List<?> trololo = new ListImpl<?>();
In general wildcard has the same meaning: you don't know fo sure will your collection be heterogenous or homogeneous?
Someday you could do:
List<something> numbers = new LinkedList<something>();
without changing client code which calls numbers
.
Declaring interface instead of implementation is indeed the rather good and widespread practice, but it is not always the best way. Use it everytime except for all of the following conditions are true:
- You are completely sure, that chosen implementation will satisfy your needs.
- You need some implementation-specific feauture, that is not available through interface, e.g.
ArrayList.trimToSize()
Of course, you may use casting, but then using interface makes no sense at all.
The first line is old style Java, we had to do it before Java 1.5 introduced generics. But a lot of brilliant software engineers are still forced to use Java 1.4 (or less), because their companies fear risk and effort to upgrade the applications...
OK, that was off the records. A lot of legacy code has been produced with java 1.4 or less and has not been refactored.
The second line includes generics (so it's clearly 1.5+) and the variable is declared as an ArrayList
. There's actually no big problem. Sure, always better to code against interfaces, so to my (and others) opinion, don't declare a variable as ArrayList
unless you really need the special ArrayList
methods.
Most of the time, when you don't care about the implementation, it's better to program to interface. So, something like:
List<something> numbers = new ArrayList<something>();
would be preferred than:
ArrayList<something> numbers = new ArrayList<something>();
The reason is you can tweak your program later for performance reason.
But, you have to be careful not to just choose the most generic interface available. For example, if you want to have a sorted set, instead of to Set, you should program to SortedSet, like this:
SortedSet<something> s = new TreeSet<something>();
If you just blatantly use interface like this:
Set<something> s = new TreeSet<something>();
Someone can modify the implementation to HashSet and your program will be broken.
Lastly, this program to interface will even be much more useful when you define a public API.
Two differences are that numbers
in the first line is of type List
, not ArrayList
. This is possible because ArrayList
is a descendant of List
; that is, it has everything that List
has, so can fill in for a List
object. (This doesn't work the other way around.)
The second line's ArrayList
is typed. This means that the second numbers
list can only hold type something
objects.
精彩评论