I saw some code go by today that was;
Writer fw = new FileWriter(--- // since ... confuses some people
I know we had a discussion the other day about;
List list = new ArrayList();
and why you would do that. I'm curious as to how many people would do
the above with FileWriter, BufferedOutputStream, or FileOutputStream.
And why would you not;
Collection c = new ArrayList();
The other question I had is what do you call that? Is it a cast? A
sort of implicit cast across assignment? Is it mentioned in the JLS
someplace?
I'm not trying to get anyone's knickers in a twist with this, I'm just
curious, so please don't take it for anything more than that.
Thanks,

Signature
Knute Johnson
email s/nospam/knute/
Lew - 08 Nov 2007 02:21 GMT
> I saw some code go by today that was;
>
[quoted text clipped - 6 lines]
> and why you would do that. I'm curious as to how many people would do
> the above with FileWriter, BufferedOutputStream, or FileOutputStream.
It depends. I've done that, but not always. The best practice is to declare
a variable to be the most general type suitable to its purpose. Writer might
lack a method that, say, PrintWriter has, and thus you'd not declare a
variable Writer if you needed that extra method.
If you don't need the specific behavior, then you absolutely should declare
the variable to be of the more general type.
> And why would you not;
>
> Collection c = new ArrayList();
You might need "c" to be a list - ordered, permissive of duplicates and
index-accessible.
> The other question I had is what do you call that? Is it a cast? A
> sort of implicit cast across assignment? Is it mentioned in the JLS
> someplace?
Upcast. The technical name is a "widening reference conversion".
<http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.5>
Joshua Bloch has a tip about this in his seminal /Effective Java/.

Signature
Lew
Owen Jacobson - 08 Nov 2007 02:25 GMT
On Nov 7, 6:09 pm, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
wrote:
> I saw some code go by today that was;
>
[quoted text clipped - 14 lines]
> sort of implicit cast across assignment? Is it mentioned in the JLS
> someplace?
It's an implicit widening reference conversion (5.1.5):
--\--
A widening reference conversion exists from any type S to any type T,
provided S is a subtype (?4.10) of T.
Widening reference conversions never require a special action at run
time and therefore never throw an exception at run time. They consist
simply in regarding a reference as having some other type in a manner
that can be proved correct at compile time.
See ?8 for the detailed specifications for classes, ?9 for interfaces,
and ?10 for arrays.
--/--
The type of the variable carries around some documentation of what
promises the code expects from the referenced object. In the case of
List<T>, I try to use the most general interface I can; if I need
get(int) but don't care much about the run time, then obviously it's
got to be a List<T> since indexed get is not provided by
Collection<T>, but if all I'm doing is iterating over the contents
then Iterable<T> might suffice (being slightly more general than
Collection<T>). If the algorithm I'm writing relies on O(1) seek
time, then I'd declare it as ArrayList (in the absence of a
"ConstantTimeSeekingList" interface :-).
With the stream decorator patterns I categorize things into sources
(which I pass around as Reader or InputStream instances) and
processors (which I pass around very little, and declare as their
concrete type). Source streams provide the basic stream, and should
be pretty much interchanable, but processors include things like
BufferedReader that provide features not available from the basic
Stream/Reader interfaces.
-O
Roedy Green - 08 Nov 2007 03:19 GMT
On Wed, 07 Nov 2007 18:09:22 -0800, Knute Johnson
<nospam@rabbitbrush.frazmtn.com> wrote, quoted or indirectly quoted
someone who said :
>And why would you not;
>
>Collection c = new ArrayList();
because List has ordering/random indexed access methods missing from
Collection, e.g. set(int index, E element);
If you did not need the random indexed access, Collection would be
appropriate. The theory is you use the interface/class with the
smallest number of methods that still lets you get the job done.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Roedy Green - 08 Nov 2007 03:22 GMT
On Wed, 07 Nov 2007 18:09:22 -0800, Knute Johnson
<nospam@rabbitbrush.frazmtn.com> wrote, quoted or indirectly quoted
someone who said :
>The other question I had is what do you call that? Is it a cast? A
>sort of implicit cast across assignment? Is it mentioned in the JLS
>someplace?
Every Dalmatian is automatically a Dog. You can use a Dog reference
to a Dalmatian, but you can only use the Dog methods. This is
explained in every basic Java text book. Someone else might point you
to the lawyerese version of it in the JLS.
see http://mindprod.com/jgloss/dalmatian.html

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Roedy Green - 08 Nov 2007 03:31 GMT
On Wed, 07 Nov 2007 18:09:22 -0800, Knute Johnson
<nospam@rabbitbrush.frazmtn.com> wrote, quoted or indirectly quoted
someone who said :
>and why you would do that. I'm curious as to how many people would do
>the above with FileWriter, BufferedOutputStream, or FileOutputStream.
Because when you use a FileWriter, BufferedOutputStream,
BufferedOutputStream, etc you often need access to all the specific
methods.
For example you would not write:
Writer caw = new CharArrayWriter(1000);
because you could not write:
char[] results = caw.toCharArray();
The catch is the various flavours of Writers are not quite as
interchangeable as Collections or Lists. The interfaces they implement
are primarily documentation to group similar classes.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Roedy Green - 08 Nov 2007 03:33 GMT
On Wed, 07 Nov 2007 18:09:22 -0800, Knute Johnson
<nospam@rabbitbrush.frazmtn.com> wrote, quoted or indirectly quoted
someone who said :
>Collection c = new ArrayList();
>
>The other question I had is what do you call that?
see http://mindprod.com/jgloss/upcasting.html
http://mindprod.com/jgloss/downcasting.html
http://mindprod.com/jgloss/cast.html

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Patricia Shanahan - 08 Nov 2007 03:35 GMT
...
> Collection c = new ArrayList();
>
> The other question I had is what do you call that? Is it a cast? A
> sort of implicit cast across assignment? Is it mentioned in the JLS
> someplace?
...
It is assignment conversion, mentioned in the description of the simple
assignment operator at
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26.1
"A compile-time error occurs if the type of the right-hand operand
cannot be converted to the type of the variable by assignment conversion
(§5.2)."
Assignment conversion, defined in section 5.2, can be any of:
# an identity conversion (§5.1.1)
# a widening primitive conversion (§5.1.2)
# a widening reference conversion (§5.1.5)
# a boxing conversion (§5.1.7) optionally followed by a widening
reference conversion
# an unboxing conversion (§5.1.8) optionally followed by a widening
primitive conversion.
In this particular case, it is a widening reference conversion.
Patricia
Mike Schilling - 08 Nov 2007 04:27 GMT
> I saw some code go by today that was;
>
> Writer fw = new FileWriter(--- // since ... confuses some people
A bit off the point, but FileWriter and FileReader are evil and/or useless,
since they don't allow an encoding to be specified. The proper way to
create a Writer that writes to files is
new OutputStreamWriter(new FileOutputStream(file), encoding)
lyallex - 08 Nov 2007 09:54 GMT
> I saw some code go by today that was;
>
[quoted text clipped - 10 lines]
>
> Collection c = new ArrayList();
I didn't read the earlier discussion so may be going over old ground
One really cool thing about interface polymorphism is that it allows you
to write components that provide clients with an abstraction, leaving
room in the brain for the things that really matter.
A component with a published interface of (say)
public List foo() tells clients that they are getting a List and should
only do List like things with it. They probably have more important
things to worry about than your implementation of the component
Internally to foo() of course I may decide to use an ArrayList to do my
work then I might use List l = new ArrayList(). Why might I do this ?
Well if, in the future some fancy new component comes along that can do
List type things in a much more efficient
way I might like to change my internal implementation to use this new
component, I certainly don't want to change the published interface as
this might break all sorts of things.
Of course I could still do ArrayList l = new ArrayList() but then when I
wanted to change I'd need to be sure that all internal references to l
were capable of handling the new type,
Of course a long as the new wizzy list thingy still implemented List the
published interface would remain unchanged.
You ask about Writer fw = new FileWriter
Well, same reason really, what happens when you decide to change your
implementation to use the new VeryFancyTCPNetworkStorageWriter class,
all your clients care about is that now they can write much faster
and that they don't need such a big disk (or whatever).
They certainly don't want to hunt down every reference to your component
and change things because you have decided to change the internal
implementation.
Anyway, just my 3 groats worth.
Patricia Shanahan - 08 Nov 2007 12:23 GMT
...
> And why would you not;
>
> Collection c = new ArrayList();
ArrayList seems an unfortunate choice of implementing class, given the
code only needs the common features of Collection. ArrayList makes some
insertions and removals expensive for the sake of efficient indexed
access. Why pay that cost if you don't need indexed access?
Collection does not make it clear whether duplicates are allowed or not,
so I would usually use either List or Set instead.
Patricia
Knute Johnson - 08 Nov 2007 16:54 GMT
> ...
>> And why would you not;
[quoted text clipped - 10 lines]
>
> Patricia
From the docs:
Collection
The JDK does not provide any direct implementations of this interface:
it provides implementations of more specific subinterfaces like Set and
List. This interface is typically used to pass collections around and
manipulate them where maximum generality is desired.
So wouldn't that suggest that Collection should be used instead of List?

Signature
Knute Johnson
email s/nospam/knute/
Hendrik Maryns - 08 Nov 2007 17:22 GMT
Knute Johnson schreef:
>> ...
>>> And why would you not;
[quoted text clipped - 21 lines]
>
> So wouldn't that suggest that Collection should be used instead of List?
It depends on what you want to do. If you use a data structure
somewhere, you will know whether you want to allow duplicates or not,
and whether you want random access etc.
Collection OTOH is to be used as argument to functions which do not care
about that. Browse around in the Collection API, you’ll get a grasp of
it. E.g. addAll() takes a Collection as argument: the class on which it
is called will take care of the duplicates-or-not-issue, that does not
depend on which kind of collection is passed to the function.
sort() OTOH will take a List as argument since order is needed to be
able to talk about sorting.
So generally, you’ll do:
List<Whatever> myList = new ArrayList<Whatever>();
Collection<Something> = functionReturningCollection; // note that it
might actually return a Set or List, or some custom implementation
public usefulMethod(Collection<Stuff> args) {
// I just want some Stuff instances, don’t care which ones, since I
only use the enhanced for loop
}
etc.
HTH, H.

Signature
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Patricia Shanahan - 08 Nov 2007 20:14 GMT
> Knute Johnson schreef:
>>> ...
[quoted text clipped - 32 lines]
> sort() OTOH will take a List as argument since order is needed to be
> able to talk about sorting.
In many case, code that creates or modifies a structure needs to know if
it is supposed to be ordered, and how it handles duplicates. Code that
only needs to process each item in its natural order is more likely to
just see it as a Collection.
Patricia
Lew - 09 Nov 2007 02:51 GMT
Knute Johnson wrote:
>> The JDK does not provide any direct implementations of this interface:
>> it provides implementations of more specific subinterfaces like Set and List.
>> This interface is typically used to pass collections around and manipulate them
>> where maximum generality is desired.
>> So wouldn't that suggest that Collection should be used instead of List?
> In many case, code that creates or modifies a structure needs to know if
> it is supposed to be ordered, and how it handles duplicates. Code that
> only needs to process each item in its natural order is more likely to
> just see it as a Collection.
The rule is, "Use the most general type *applicable*."
Not, "Use the most general type."
If a Collection doesn't support what your algorithm needs, use the more
specific type that does, but nothing more specific than that.
So in Patricia's example, if the algorithm requires an ordered collection that
tolerates duplicates, use a List. A Collection will not have access to the
behaviors that you need. If the algorithm only requires that you iterate
through the collection, use Iterable; you don't even need a Collection.
So to Knute's question - that Collection is more general than List does not
automatically require the variable to be of type Collection. It is even valid
to declare a variable to be of a specific implementing class, if the full
behavior set of that class is what you need. This is the case, for example,
with java.util.Properties - it is really never used as a Map.

Signature
Lew
Daniel Pitts - 08 Nov 2007 16:54 GMT
> ....
>> And why would you not;
[quoted text clipped - 10 lines]
>
> Patricia
Although, perhaps you only need to collect things, and leave it to the
generator of the Collection instance whether they want duplication
allowed or ordering.
I think the line would be better off as
Collection c = getSomeThings();
Now, someThings may decide to return a list, set, or some other
implementation of Collection.

Signature
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
Knute Johnson - 08 Nov 2007 16:57 GMT
> ...
>> And why would you not;
[quoted text clipped - 10 lines]
>
> Patricia
And one more question and I'll let this go back to where it was.
Is there any reason to do this for classes created on the stack?

Signature
Knute Johnson
email s/nospam/knute/
Lew - 09 Nov 2007 03:04 GMT
> And one more question and I'll let this go back to where it was.
>
> Is there any reason to do this for classes created on the stack?
Are you talking about anonymous and local classes? If not, what do you mean?
You have no choice but to declare anonymous classes as some more general type
by the very syntax of anonymous class declaration.
You wouldn't declare a local class unless you needed its specific behavior.
So while the rule could be said to apply ("Use the most general type
applicable"), the local class type is going to be the most general type
applicable.

Signature
Lew