Discussion:
unchecked or unsafe operations??
(too old to reply)
Jonie
2005-12-21 18:31:31 UTC
Permalink
Hi,
when I compile Model file (see below) with other classess I get the
message that says "Model.java uses unchecked or unsafe operations". It
seems to me that program runs fine, but I want to know why this happens
and, if possible, fix it. Thank you.

- Jonie

--------------------------------------------------------------------------
import java.util.*;
import java.util.Scanner;
import java.awt.Point;
import uchicago.src.sim.space.*;
import uchicago.src.sim.gui.*;

public class Model {
private int numberOfAnts = 8;
private int numberOfAntEaters = 2;
private ArrayList <Ant> antList;
private ArrayList <AntEater> antEaterList;
private ArrayList allList;
private int worldSizeX = 10, worldSizeY = 10;
private Object2DGrid world;
private Object2DDisplay worldDisplay;
private DisplaySurface dsurf;
private java.util.Random rng;


public void initializeModel () {
System.out.printf( "-> Entering initalizeModel...\n" );

rng = new java.util.Random();
Animal.setRNG( rng );
Animal.setModel( this );

// create a world for the Ants to live in, and a list to keep track of
them
world = new Object2DGrid( worldSizeX, worldSizeY );
antList = new ArrayList <Ant> ();
antEaterList = new ArrayList <AntEater> ();
allList = new ArrayList ();

// lets create a bunch of ants, adding them to the antList
// and placing them randomly in the world ( <= 1 per cell ).
System.out.printf( "\nCreate %d ants...", numberOfAnts );
for ( int i = 0; i < numberOfAnts; ++i ) {
Ant anAnt = new Ant( );
int x, y;
do { // keep sampling spots until we find an empty one
x = rng.nextInt( worldSizeX );
y = rng.nextInt( worldSizeY );
} while ( world.getObjectAt( x, y ) != null );
anAnt.setX( x );
anAnt.setY( y );
world.putObjectAt( x, y, anAnt );
antList.add( anAnt );
allList.add( anAnt );
}
// lets create a bunch of antEaters, adding them to the antEaterList
// and placing them randomly in the world ( <= 1 per cell ).
System.out.printf( "\nCreate %d ants...", numberOfAnts );
for ( int i = 0; i < numberOfAntEaters; ++i ) {
AntEater anAntEater = new AntEater( );
int x, y;
do { // keep sampling spots until we find an empty one
x = rng.nextInt( worldSizeX );
y = rng.nextInt( worldSizeY );
} while ( world.getObjectAt( x, y ) != null );
anAntEater.setX( x );
anAntEater.setY( y );
world.putObjectAt( x, y, anAntEater );
antEaterList.add( anAntEater );
allList.add( anAntEater );
}



// Lets create the objects to display the ants on the screen
dsurf = new DisplaySurface( null, "Ant Display" );
worldDisplay = new Object2DDisplay( world );
worldDisplay.reSize( 200, 200 );
dsurf.addDisplayable( worldDisplay, "Ants");
dsurf.display();

System.out.printf( "The initial ants:\n" );
printAntList( antList );
System.out.printf( "The initial anteaters:\n" );
printAntEaterList( antEaterList );
System.out.printf( "The initial objects in the world:\n" );
printWorld();
System.out.printf( "\n<- Leaving initalizeModel.\n" );
}


// run
// repeatedly ask the user for a number of "time steps" to run the
model.
// (prompt in the terminal window where the program was started).
// If 0, stop the program.
// Otherwise execute the Model step() message the requested number
of steps,
// and ask again.
// NB: no real checking on the input (eg is it an int, etc).
//
public void run ( ) {
//... Initialize Scanner to read from console.
Scanner input = new Scanner(System.in);
int steps = 0;

do {
System.out.printf( "Enter int number of steps (0->stop): " );
steps = input.nextInt();
for ( int s = 0; s < steps; ++s ) {
step();
}
} while ( steps != 0 );

}

// step
// Execute all activity for one "time step" of the model
// In this simple model, just:
// - tell each Ant to execute its step() method
// - tell the displaySurface to update itself
//
public void step () {
System.out.printf( " -> Take a Model step...\n" );

for ( int i = 0; i < allList.size(); ++i ) {
Object obj = allList.get(i);
if (obj.getClass() == Ant.class )
((Ant) obj).step();
else
((AntEater) obj).step();
}

dsurf.updateDisplay();
System.out.printf( "- antList now:\n" );
printAntList( antList );
System.out.printf( "- antEaterList now:\n" );
printAntEaterList( antEaterList );
printWorld();
System.out.printf( "\n" );
}

// moveObjectInWorld
// try to move object to the requested dx,dy .
// note we must check to be sure the new location is "legal",
// i.e., cell is empty and cell is not off the edge of the world.
// NB: if either new* values is illegal, don't move.
// If move is ok:
// - tell the world the object is not where it was
// - tell the world the object is now at the new* location
// Return: null if not moved, otherwise return a Point object
// with new x,y values.
//
public Point moveObjectInWorld ( Drawable obj, int dX, int dY ) {

int newX = obj.getX() + dX; // get location it wants to move to
int newY = obj.getY() + dY;

// first check to be sure new location is in the world!
if ( newX < 0 || newY < 0 || newX >= worldSizeX || newY >= worldSizeY
) {
System.out.printf( " - obj tried to move offworld (%d,%d).\n",
newX, newY );
return null;
}
// see if new cell is empty.
if ( world.getObjectAt( newX, newY ) != null ) {
System.out.printf( " - obj tried to move to occupied cell
(%d,%d).\n",
newX, newY );
return null;
}

// its ok to move, so tell the world and the object
world.putObjectAt( obj.getX(), obj.getY(), null ); // old cell empty
now
world.putObjectAt( newX, newY, obj ); // obj in new cell now
Point loc = new Point( newX, newY );
return loc;
}

// printAntList
// a method to print the contents of an Ant list
public static void printAntList ( ArrayList <Ant> list ) {
for ( Ant a : list ) {
a.printSelf();
}
}
// printAntEaterList
// a method to print the contents of an Ant list
public static void printAntEaterList ( ArrayList <AntEater> list )
{
for ( AntEater a : list ) {
a.printSelf();
}
}
// printWorld
// print places where objects are in the world, and total
public void printWorld () {
System.out.printf( "-> The world contents:\n" );
int numObjs = 0;
for ( int x = 0; x < worldSizeX; ++x ) {
for ( int y = 0; y < worldSizeY; ++y ) {
if ( world.getObjectAt( x, y ) != null ) {
System.out.printf( " object at %d,%d.\n", x, y );
++numObjs;
}
}
}
System.out.printf( "<- %d objects in the world.\n", numObjs );
}
}
Bart Cremers
2005-12-21 19:18:43 UTC
Permalink
Post by Jonie
Hi,
when I compile Model file (see below) with other classess I get the
message that says "Model.java uses unchecked or unsafe operations". It
seems to me that program runs fine, but I want to know why this happens
and, if possible, fix it. Thank you.
- Jonie
This is happening because the ArrayList allList isn't "generified".
Define the ArrayList with a common supertype: ArrayList<supertype>.
Even ArrayList<Object> will do and should resolve the warning.

Bart
Jonie
2005-12-21 19:25:56 UTC
Permalink
Thank you, Bart. Following your advice, I was able to get rid of those
warnings.
Kent Paul Dolan
2005-12-22 07:22:32 UTC
Permalink
Post by Jonie
Thank you, Bart. Following your
advice, I was able to get rid of those
warnings.
Well, don't be thanking Bart too fast, he
just handed you a loaded gun and forgot to
tell you which end emits the bullets.

Those warnings are there for a _reason_, not
just as an exercise in how to make them go
away without understanding, in detail, why
you are being warned.

In the current case, you are caught by the
issue that despite Java being strongly typed,
some kinds of containers will accept entries
added to them without being too fussy about
just what class of objects are being added.
[This can happen because the entries are
object _references_, which are all the same
size and so fit in the array without problems.]

What you are being warned, is that by taking
advantage of this laxness of containers, you
are sacrificing one of the major benefits of
strongly typed programming languages: help from
the compiler to assure that you are applying
"core" to apples and "squeeze" to oranges.

The fix the warnings _want_ you to take is
1) to redeclare your container with the minimum
needed (closest available) superclass that will
hold all the kinds of objects it is intended to
contain; for an array intended to hold both Ants
and Aardvarks, this might be a superclass called
"Animal", for example.

Then, 2) each place you put a something into that
array, cast the _array_ to that superclass,
so that type checking is done that what is going
into the array is what it was intended to contain,
some subclass of that superclass.

instead of:

allList.add( anAnt );

do:

( (Animal) allList ).add( anAnt );

Now your anAnt is checked to make sure that it is
at least a subclass of class Animal, and you are
no longer doing an unchecked operation.

The reason to do this instead of casting to Object,
is that the above check prevents you from doing:

( (Animal) allList ).add( aCadillac );

(presuming aCadillac is not a subtype of Animal)
_and the check does that at +compile+ time_ not at
run time, so that you see the error _before_ you
run the program!

If you do

( (Object) allList ).add( aCadillac );

on the other hand, the compiler won't complain,
and only at run time will you find out how bad
an idea it is to attempt to do

( allList[i] ).danceTheMacarena();

when entry i contains aCadillac.

HTH

xanthian.


Loading Image...
--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG
Kent Paul Dolan
2005-12-22 07:30:30 UTC
Permalink
Post by Kent Paul Dolan
http://www.anycities.com/user/xanthian/TravellerArt/AntDoingTheMacarena2.jpg
Piffle! I forgot greedy Anycities.com won't
let you look at a picture without looking at
their stinking ads first. Instead go here,
and see the third art link in the list on
the page.

http://www.anycities.com/user/xanthian/TravellerArt/TravellerArt09.html

Grrrr.

xanthian.
--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG
Hendrik Maryns
2005-12-22 11:12:29 UTC
Permalink
Kent Paul Dolan bracht de volgende tekst voort op 22/12/2005 8:22:

<snip good explanation untill here>
Post by Jonie
allList.add( anAnt );
( (Animal) allList ).add( anAnt );
I very much doubt an animal has an add method. I don’t even know where
you’re getting at here.
Post by Jonie
Now your anAnt is checked to make sure that it is
at least a subclass of class Animal, and you are
no longer doing an unchecked operation.
No, this checking happens automatically if allList is declared to be a
List<Animal>.
Post by Jonie
The reason to do this instead of casting to Object,
( (Animal) allList ).add( aCadillac );
More nonsense.
Post by Jonie
(presuming aCadillac is not a subtype of Animal)
_and the check does that at +compile+ time_ not at
run time, so that you see the error _before_ you
run the program!
If you do
( (Object) allList ).add( aCadillac );
This certainly is impossible. Object does not have an add method.
Post by Jonie
on the other hand, the compiler won't complain,
and only at run time will you find out how bad
an idea it is to attempt to do
( allList[i] ).danceTheMacarena();
when entry i contains aCadillac.
Back on the right track here. Are you confused about the syntax?

H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
Kent Paul Dolan
2005-12-22 12:25:23 UTC
Permalink
Post by Hendrik Maryns
Back on the right track here. Are you confused about the syntax?
Yes, due to tiredness from weeks of overwork. I left out a bunch of
intended array brackets of the

( (Animal []) allList ).add( aCadillac);

sort, but more probably it should have been something much more
like

( (Container<Animal>) allList ).add( aCadillac);

or some such, I'm still too blind tired to read my own writing, sorry.

xanthian.
Oliver Wong
2005-12-21 20:15:58 UTC
Permalink
Post by Bart Cremers
Post by Jonie
Hi,
when I compile Model file (see below) with other classess I get the
message that says "Model.java uses unchecked or unsafe operations". It
seems to me that program runs fine, but I want to know why this happens
and, if possible, fix it. Thank you.
- Jonie
This is happening because the ArrayList allList isn't "generified".
Define the ArrayList with a common supertype: ArrayList<supertype>.
Even ArrayList<Object> will do and should resolve the warning.
Putting "<Object>" everywhere just to get rid of the warnings is sort of
like putting "synchronized" everywhere just to make your program threadsafe.
I.e., not nescessarily a good idea.

If the OP wants to a pointer in the right direction to where (s)he can
find out what the "best practices" are for resolving the warnings, (s)he
should google for "generics" and "java". Sun's own guide to the topic is at:

http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html

- Oliver
Bart Cremers
2005-12-22 07:33:14 UTC
Permalink
Well, maybe I shouldn't have put Object in the example, I still believe
it's better to put <Object> then to put nothing, IF, and only if,
you're sure anything can be put in the collection.

It's not a case of getting rid of the compiler warnings, but a way to
show you've thought about the possible types in the collection and
Object is the only good solution.

For the given example, Drawable or Animal are probably the best
matches, but from the given code I could not be 100% sure, so I gave
Object as example.

Regards,

Bart
Oliver Wong
2005-12-22 17:56:06 UTC
Permalink
Post by Bart Cremers
Well, maybe I shouldn't have put Object in the example, I still believe
it's better to put <Object> then to put nothing, IF, and only if,
you're sure anything can be put in the collection.
It's not a case of getting rid of the compiler warnings, but a way to
show you've thought about the possible types in the collection and
Object is the only good solution.
Fair enough, but if the programmer has NOT put any thought about the
possible types in the collection (which I think is the case here, since the
OP seemed unfamiliar with generics), then perhaps it is best to put nothing
at all, thus making it explicit that (s)he hasn't though about it.

If it says <Object>, I assume the programmer meant <Object>, and not "I
haven't thought about it carefully yet."

Not sure about the syntax, but the author might want to use this to
indicate uncertainty:

List<? extends Object>

but again, I think simply putting nothing and accepting the warnings
until you understand the implications of what you're doing, is better.

- Oliver
Roedy Green
2005-12-21 22:48:18 UTC
Permalink
Post by Jonie
when I compile Model file (see below) with other classess I get the
message that says "Model.java uses unchecked or unsafe operations". It
seems to me that program runs fine, but I want to know why this happens
and, if possible, fix it. Thank you.
see http://mindprod.com/jgloss/generics.html
and follow links.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.
r***@gmail.com
2005-12-22 12:53:43 UTC
Permalink
interface Animal
{
void step();
}

final class Ant implements Animal
{
public void step()
{
...
}
}

final class Anteater implements Animal
{
public void step()
{
...
}
}

final class Main
{
public static void main(final String[] args)
{
final List<Ant> ants=Arrays.asList(new Ant(),new Ant(),new
Ant());
final List<Anteater> anteaters=Arrays.asList(new Anteater(),new
Anteater());
final List<Animal> animals=new ArrayList<Animal>();

animals.addAll(ants);
animals.addAll(anteaters);

for (final Animal animal: animals)
animal.step();
}
}

Kent Paul Dolan seems to be confused. Due to generics, we don't need
any typecasts now, except when working with broken/old APIs.
Kent Paul Dolan
2005-12-22 13:07:10 UTC
Permalink
Post by r***@gmail.com
Kent Paul Dolan seems to be confused. Due to
generics, we don't need any typecasts now, except
when working with broken/old APIs.
Yes, I was confused.

No, generics do not remove the need to understand
the error messages emitted when generics are not
used, in the context in which those messages were
originally drafted, even if generics may provide an
alternative way to solve the problems.

In the context of the error messages at their date
and time of creation, typecasts were the preferred
solution, and the modern Java programmer still needs
to understand them, and why their being missing will
produce the messages the OP received.

HTH

xanthian.
Kent Paul Dolan
2005-12-23 23:11:17 UTC
Permalink
That is, by the way, now that I've had some sleep,
quite a pretty exposition you gave.

xanthian.

Continue reading on narkive:
Loading...