Generics warning message.

R

Roedy Green

Is there a way to get rid of this warning message?

E:\com\mindprod\vercheck\VerCheck.java:575: warning: [unchecked]
unchecked cast
found : java.lang.Object
required: java.util.ArrayList<com.mindprod.vercheck.AppToWatch>
allRows = (ArrayList<AppToWatch>) ois.readObject();

the code is

ArrayList<AppToWatch> allRows = new ArrayList<AppToWatch>(30);
....
allRows = (ArrayList<AppToWatch>) ois.readObject();
 
E

External Concepts Guild

Is there a way to get rid of this warning message?

E:\com\mindprod\vercheck\VerCheck.java:575: warning: [unchecked]
unchecked cast
found : java.lang.Object
required: java.util.ArrayList<com.mindprod.vercheck.AppToWatch>
allRows = (ArrayList<AppToWatch>) ois.readObject();

the code is

ArrayList<AppToWatch> allRows = new ArrayList<AppToWatch>(30);
...
allRows = (ArrayList<AppToWatch>) ois.readObject();
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

There might be a way. I think the following code performs a similar
function to what you are trying to achieve. The code compiles without
warnings or errors and it runs correctly. Nonetheless, it leaves
something to be desired.

import java . io . * ;
import java . util . * ;

class test
{
public static void main ( String [ ] args ) throws Exception
{
ObjectInputStream ois = setupExample ( args ) ;
runExample ( ois ) ;
}

/**
* This just sets up the example.
* It returns an appropriate ObjectInputStream
* (i.e. one that has been stuffed with an ArrayList.
**/
private static ObjectInputStream setupExample ( String [ ] args )
throws Exception
{
ArrayList < String > list = new ArrayList < String > ( ) ;
for ( int i = 0 ; i < args . length ; i ++ )
{
list . add ( args [ i ] ) ;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream ( ) ;
ObjectOutputStream oos = new ObjectOutputStream ( bos ) ;
oos . writeObject ( list ) ;
oos . close ( ) ;
bos . close ( ) ;
byte [ ] b = bos . toByteArray ( ) ;
ByteArrayInputStream bis = new ByteArrayInputStream ( b ) ;
ObjectInputStream ois = new ObjectInputStream ( bis ) ;
return ( ois ) ;
}

/**
* This is the example.
* We think that there is an ArrayList<java.lang.String> in
* the InputStream.
* How to cast it out without throwing warnings?
**/
private static void runExample ( ObjectInputStream ois ) throws
Exception
{
Object object = ois . readObject ( ) ;
ArrayList list1 = ( ArrayList ) ( object ) ;
ArrayList < String > list2 = nowarningCast ( String . class ,
list1 ) ;
for ( String string : list2 )
{
System . out . println ( string ) ;
}
}

/**
* This is how I cast the ArrayList to
* an ArrayList<java.lang.String> without
* casting warnings.
*
* Take heed that this is not safe.
**/
private static < R > ArrayList < R > nowarningCast
( Class < R > clazz , ArrayList in )
{
ArrayList < R > out = new ArrayList < R > ( ) ;
for ( Object val : in )
{
R r = clazz . cast ( val ) ;
out . add ( r ) ;
}
return ( out ) ;
}
}

Emory Merryman
External Concepts Guild
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQFHd99XVQdj5Q2e9q0RAgPmAJ9rPJDnt0ebyjVFd2hCLVCU0sjJQACdE7Aj
hniuYd99CXmdjmT1JVk5w+o=
=2Un1
-----END PGP SIGNATURE-----
 
L

Lew

External said:
There might be a way. I think the following code performs a similar
function to what you are trying to achieve. The code compiles without
warnings or errors and it runs correctly. Nonetheless, it leaves
something to be desired.

private static < R > ArrayList < R > nowarningCast
( Class < R > clazz , ArrayList in )
{
ArrayList < R > out = new ArrayList < R > ( ) ;
for ( Object val : in )
{
R r = clazz . cast ( val ) ;
out . add ( r ) ;
}
return ( out ) ;
}
}

That's not a cast, that's a copy. But I'll bet you could do a cast with a
Class<ArrayList<R>> with a similar idiom.
 
E

External Concepts Guild

That's not a cast, that's a copy. But I'll bet you could do a cast with a
Class<ArrayList<R>> with a similar idiom.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


You are absolutely correct: it is a copy not a cast. I believe that
because of the nature of type erasure <http://java.sun.com/docs/books/
tutorial/java/generics/erasure.html> it is impossible to do a cast
(without at least generating a warning). Thus to achieve the effect
that the OP desires, it is necessary to cheat (e.g. copying rather
than casting).

If you have control of the writing operation as well as the reading,
then you could solve this problem by using a nonparameterized
extension of ArrayList<R>. For example, consider class MyArrayList
extends ArrayList<String> { }. If you wrote a MyArrayList, then you
should be able to read it and cast it without warnings.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQFHeRMOVQdj5Q2e9q0RAnhKAJ0ZEYpep1as38WX0VcLwORMP/+AkACfYoSG
KBxX6RsV4q17sFOg3muG0Og=
=i8ZY
-----END PGP SIGNATURE-----
 
Z

Zig

You are absolutely correct: it is a copy not a cast. I believe that
because of the nature of type erasure <http://java.sun.com/docs/books/
tutorial/java/generics/erasure.html> it is impossible to do a cast
(without at least generating a warning). Thus to achieve the effect
that the OP desires, it is necessary to cheat (e.g. copying rather
than casting).

If I may rephrase your answer here with a bit of code; if we had a write
method doing something like:

ObjectOutputStream out=...
ArrayList<FooBar> objs=new ArrayList<FooBar>();
objs.add(new FooBar());
out.writeObject(objs);

And later we read that back as:

ObjectInputStream in=...
ArrayList<AppToWatch> objs=(ArrayList<AppToWatch>) in.readObject();

Then the cast would succeed, but iterating through the list after it had
been read would throw spurious ClassCastExceptions (hence the warning).
If you have control of the writing operation as well as the reading,
then you could solve this problem by using a nonparameterized
extension of ArrayList<R>. For example, consider class MyArrayList
extends ArrayList<String> { }. If you wrote a MyArrayList, then you
should be able to read it and cast it without warnings.

Reading each object individually is a good solution, as it causes you to
validate each object by casting it. Having a implementation with a fixed
type works too: it makes one *wish* Collections.checkedList would return a
public type, so you could ensure that

CheckedList.getCheckedType()==AppToWatch.class

But, the easiest solution to remove the warning is probably to decorate
the read method with

@SuppressWarnings("unchecked")

Obviously, this works when you can safely say that the content of the
input stream only comes from well known and trusted write methods (as it
is not verifying the contents of the list for type accuracy).

HTH,

-Zig
 

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,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top