Genercis advice

N

Nomak

Hello!

i've just read some docs about generics in Java, and i would like to do
a complete Canvas class. Here is my attempt:

import java.util.LinkedList;
import java.util.List;

public class Canvas {
private List<Shape> shapeList = null;

class Shape {
public void draw() {
}
}

class SubShape extends Shape {
public void draw() {
}
}

public Canvas() {
shapeList = new LinkedList<Shape>();

add(new SubShape());
drawAll();
}

public void drawAll() {
// TEH UGLYNESS !!!
List<? extends Shape> shapeList = this.shapeList;

for (Shape s:shapeList)
s.draw();
}

public void add(Shape s) {
shapeList.add(s);
}
}

From what i've understood:
- unbounded is for writing
- bounded is for reading

So basically, i have to use temporaries or i have to do a
"drawAll(bounded version)" wich is even worse.

I really hope i've missed something because i think this stink.

Any advice/explaination apreciated :)
 
C

Chris Smith

Nomak said:
public class Canvas {
private List<Shape> shapeList = null;

....

public void drawAll() {
// TEH UGLYNESS !!!
List<? extends Shape> shapeList = this.shapeList;

for (Shape s:shapeList)
s.draw();
}

That is allowed, but unnecessary. You could just as easily use a
reference to List<Shape> there, instead of List<? extends Shape>. The
difference is that a variable of type List<? extends Shape> can point to
an object of class List<Rectangle> (for example). Since the field
shapeList is of type List<Shape> and you don't assign anything else to
the local variable, that extra flexibility doesn't actually accomplish
anything here. However it doesn't hurt anything either, since a mere
So basically, i have to use temporaries or i have to do a
"drawAll(bounded version)" wich is even worse.

No, you don't have to do any of that. You must have seen an example
explaining what you *can* do, and misinterpreted it as something that
you *must* do.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
M

Mr Smith

That is allowed, but unnecessary. You could just as easily use a
reference to List<Shape> there, instead of List<? extends Shape>. The
difference is that a variable of type List<? extends Shape> can point to
an object of class List<Rectangle> (for example). Since the field
shapeList is of type List<Shape> and you don't assign anything else to
the local variable, that extra flexibility doesn't actually accomplish

you must have misread the constructor: there is a SubShape added to the list
 
J

Jesper Nordenberg

Nomak said:
Hello!

i've just read some docs about generics in Java, and i would like to do
a complete Canvas class. Here is my attempt:

import java.util.LinkedList;
import java.util.List;

public class Canvas {
private List<Shape> shapeList = null;

class Shape {
public void draw() {
}
}

class SubShape extends Shape {
public void draw() {
}
}

public Canvas() {
shapeList = new LinkedList<Shape>();

add(new SubShape());
drawAll();
}

public void drawAll() {
// TEH UGLYNESS !!!
List<? extends Shape> shapeList = this.shapeList;

for (Shape s:shapeList)
s.draw();
}

public void add(Shape s) {
shapeList.add(s);
}
}

From what i've understood:
- unbounded is for writing
- bounded is for reading

So basically, i have to use temporaries or i have to do a
"drawAll(bounded version)" wich is even worse.

I really hope i've missed something because i think this stink.

Any advice/explaination apreciated :)

What are you trying to achieve? What's the point of the local variable
in drawAll()? Why not loop over the shapeList field?

/Jesper Nordenberg
 
M

Mr Smith

On 7 Mar 2005 01:41:50 -0800
What are you trying to achieve? What's the point of the local variable
in drawAll()? Why not loop over the shapeList field?

You made me doubtful, so i try to compile a modified version of the code:

import java.util.LinkedList;
import java.util.List;

public class Canvas {
private List<Shape> shapeList = null;

class Shape {
public void draw() {
System.out.println("Shape.draw()");
}
}

class Circle extends Shape {
public void draw() {
System.out.println("Circle.draw()");
}
}

class Rectangle extends Shape {
public void draw() {
System.out.println("Rectangle.draw()");
}
}

public Canvas() {
shapeList = new LinkedList<Shape>();

add(new Circle());
add(new Rectangle());
drawAll();
}

public void drawAll() {
for (Shape s:shapeList)
s.draw();
}

public void add(Shape s) {
shapeList.add(s);
}

// Entry point
public static void main(String[] args) {
Canvas c = new Canvas();
}
}

The output:

$ java -version
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)
$ javac Canvas.java
$ java Canvas
Circle.draw()
Rectangle.draw()
$

So it works great... but from this document:

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf


It is said that for dynamic dispatch on Shape.draw() in drawAll(), the collection must be on "? extends Shape". So my code shouldn't work... i don't understand :(

Was the generics modified in "update 1" of JSE 5.0 ?
 
C

Chris Smith

Mr Smith said:
you must have misread the constructor: there is a SubShape added to the list

No, I did not misread the constructor. Despite there being a SubShape
added to the list, the list itself has a class of List<Shape>. The
single most important thing to get straight in generic collections is
that the class of a collection does *not* depend on what's in it. I can
have a List<Object> that contains only JComponent instances... but it's
still NOT a List<JComponent> if I created it by writing something like
"lst = new List<Object>()".

In your case, the field shapeList points to an object of the collection
class List<Shape>, and NOT List<SubShape>. Because SubShape is
assignable to Shape, it's possible to add a SubShape to shapeList, but
that doesn't change the class of the object.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
L

Lasse Reichstein Nielsen

Mr Smith said:
So it works great... but from this document:

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf


It is said that for dynamic dispatch on Shape.draw() in drawAll(), the collection must be on "? extends Shape". So my code shouldn't work... i don't understand :(

Without checking the tutorial, I guess it's because the Canvas in there is
parameterized by the List of shapes.

You have fixed on a List<Shape>, so you can use that you know that.

They have the list provided to them, and all all they require is that
Was the generics modified in "update 1" of JSE 5.0 ?

No.

/L
 
J

Jesper Nordenberg

Mr Smith said:
So it works great... but from this document:

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf


It is said that for dynamic dispatch on Shape.draw() in drawAll(), the collection must be on "? extends Shape". So my code shouldn't work... i don't understand :(

No, it doesn't say that. It's a common misconception people have with
generics. List<Shape> means a list which contains instances of Shape
or any sub class of Shape, so you can call any method in Shape on the
objects in the list. List<? extends Shape> means a list of Shapes or a
sub class of Shape. So, both List<Shape> and List<SubShape> fits this
wildcard. The difference between List<Shape> and List<? extends Shape>
is when you call methods on the List. For example, you can't add a
Shape to a List<? extends Shape> because it might not be a list of
Shapes.

/Jesper Nordenberg
 
M

Mr Smith

On 8 Mar 2005 00:57:46 -0800
No, it doesn't say that. It's a common misconception people have with
generics. List<Shape> means a list which contains instances of Shape
or any sub class of Shape, so you can call any method in Shape on the
objects in the list. List<? extends Shape> means a list of Shapes or a
sub class of Shape. So, both List<Shape> and List<SubShape> fits this
wildcard. The difference between List<Shape> and List<? extends Shape>
is when you call methods on the List. For example, you can't add a
Shape to a List<? extends Shape> because it might not be a list of
Shapes.

thx a lot !!!

i've read again the page 6 of the pdf, and with your explaination standing next to the pdf, i understood it right :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top