unchecked cast

S

senderj

How can I avoid such warning when compiling my program:
C:\Dev\simDeal.java:75: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.TreeSet<stock.trade.simDeal.myDeal>
dealList = (TreeSet<myDeal>) si.readObject();

My coding is like this:
TreeSet<myDeal> dealList = new TreeSet<myDeal>();
FileInputStream fi = new FileInputStream("dealList.treeset");
ObjectInputStream si = new ObjectInputStream(fi);
dealList = (TreeSet<myDeal>) si.readObject();

Please help.
 
L

Lew

senderj said:
How can I avoid such warning when compiling my program:
C:\Dev\simDeal.java:75: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.TreeSet<stock.trade.simDeal.myDeal>

Class names should start with an upper-case letter, by convention. Package
names should comprise only lower-case letters, by somewhat less stringent
convention.
dealList = (TreeSet<myDeal>) si.readObject();

My coding is like this:
TreeSet<myDeal> dealList = new TreeSet<myDeal>();

Why assign a new object only to throw away the new object without using it?

If it's a 'Set', why does the variable name imply that it's a 'List'?
FileInputStream fi = new FileInputStream("dealList.treeset");
ObjectInputStream si = new ObjectInputStream(fi);
dealList = (TreeSet<myDeal>) si.readObject();

Please help.

Read and study:
<http://java.sun.com/docs/books/effective/generics.pdf>
(from <http://java.sun.com/docs/books/effective/index.html>)

In a nutshell, casting to a generic type "doesn't work", because casting
happens at run time only, and generics happen at compile time only. The
workaround is to use '@SuppressWarnings("unchecked")' annotation
*judiciously*. Such use must include a comment as to how you are preventing
any 'ClassCastException', such as:

@SuppressWarnings( "unchecked" ) // only MyDeals in serialized store
TreeSet <MyDeal> deals = (TreeSet <MyDeal>) si.readObject();

There are restrictions on where you get to use the annotation. Use it at the
narrowest possible scope at the earliest possible point, almost always at the
declaration of a variable. This gives the benefits of generics for the
longest possible time.

Note that this example doesn't really guarantee that you won't get
'ClassCastException' or worse, in the event of a surprise input file. It does
reduce the range of possible sources for a bug if there is such a surprise,
which helps the repair.
 
A

Arne Vajhøj

senderj said:
How can I avoid such warning when compiling my program:
C:\Dev\simDeal.java:75: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.TreeSet<stock.trade.simDeal.myDeal>
dealList = (TreeSet<myDeal>) si.readObject();

My coding is like this:
TreeSet<myDeal> dealList = new TreeSet<myDeal>();
FileInputStream fi = new FileInputStream("dealList.treeset");
ObjectInputStream si = new ObjectInputStream(fi);
dealList = (TreeSet<myDeal>) si.readObject();

I think the only thing you can do is to use:

@SuppressWarnings("unchecked").

on that cast.

Arne
 
L

Lew

Arne said:
I think the only thing you can do is to use:

@SuppressWarnings("unchecked").

on that cast.

Appropriately commented after appropriate analysis, and at a declaration
(since the annotation won't work the way the OP wrote the cast line).

(But that's OK, since the line should have been a declaration anyway.)
 
A

Andreas Leitgeb

Arne Vajhøj said:
I think the only thing you can do is to use:
@SuppressWarnings("unchecked").
on that cast.

It may be the most reasonable/effective one in most cases, but
it's not the only one.

Now addressing the OP:

If you really wanted to be sure to have a valid TreeSet<myDeal>,
write an auxiliary method like this:

TreeSet<myDeal> ensureMyDealSet (TreeSet ots)
{
TreeSet<myDeal> nts = new TreeSet<myDeal>();
for (Object md : ots) { nts.add( (myDeal) md ); }
return nts;
}
...
dealList = ensureMyDealSet ( (TreeSet) si.readObject() );

With this code, if it gets as far as to assign a result to "dealList",
you can be damn sure that you got the right type of Objects in the Set.
It should compile without any "unchecked"-warnings, even if they're
not suppressed.

PS: Although I used the original identifiers, I totally agree to Lew's
reply, where he points out the conventions for proper casing of
identifiers and that a Set-typed variable shouldn't have "List"
in its name.
 
W

Wojtek

Lew wrote :
Package names should comprise only lower-case letters, by somewhat less
stringent convention.

Camel case. Start with a lowercase letter though.
 
L

Lew

Lew wrote :


Camel case. Start with a lowercase letter though.

According to the JLS:
The first component of a unique package name
is always written in all-lowercase ASCII letters
and should be one of the top level domain names ...

The Sun naming convention document says:
Subsequent components of the package name vary according
to an organization's own internal naming conventions.
Such conventions might specify that certain directory name
components be division, department, project, machine,
or login names.

The examples given in that document are not camel case but all lower
case, for example, "com.apple.quicktime.v2". Notice that they do not
suggest "quickTime".

OTOH, in another part of the document they give the example "import
java.blah.blahdy.BlahBlah;". Note that they do not begin the last
component with a lower-case letter.

The JLS suggests use of underscores in package names as well.

The official convention is to use whatever local convention one wants
for second and subsequent package name parts, but the first part
should be all lower case. In practice, nearly all package names I've
seen have been all lower-case, but the rules are "less stringent" than
for classes, variables, methods, etc. I find the presence of upper-
case letters in package names rather jarring, being so unexpected and
all, but it's not technically a violation of the convention, nor is
failing to use camel case.
 
L

Lars Enderin

Lew said:
The examples given in that document are not camel case but all lower
case, for example, "com.apple.quicktime.v2". Notice that they do not
suggest "quickTime".

OTOH, in another part of the document they give the example "import
java.blah.blahdy.BlahBlah;". Note that they do not begin the last
component with a lower-case letter.

BlahBlah is probably a class name.
 
L

Lew

BlahBlah is probably a class name.

Oh, of course. Duhh. Well, that only serves to support the notion
that packages are written lower-case in Sun's world, though not
necessarily everywhere, since the examples in their coding conventions
document consistently use all lower case letters.

The official convention is to do what you want; unofficially most
package names seem to go for lower-case letters. I can find nothing
to suggest that the convention for package names is camel case.
 
T

Tom Anderson

It may be the most reasonable/effective one in most cases, but
it's not the only one.

Now addressing the OP:

If you really wanted to be sure to have a valid TreeSet<myDeal>,
write an auxiliary method like this:

TreeSet<myDeal> ensureMyDealSet (TreeSet ots)
{
TreeSet<myDeal> nts = new TreeSet<myDeal>();
for (Object md : ots) { nts.add( (myDeal) md ); }
return nts;
}
...
dealList = ensureMyDealSet ( (TreeSet) si.readObject() );

I'd do:

public <T> SortedSet<T> cast(Class<T> cl, SortedSet<?> set) {
for (Object obj: set) {
cl.cast(obj) ;
}
@SuppressWarnings("unchecked")
SortedSet<T> ret = (SortedSet<T>)set ;
return ret ;
}

Yes, it uses an unchecked cast - but only after the appropriate check has
been done manually. And it doesn't involve allocating anything except an
iterator.

tom

--
The Gospel is enlightened in interesting ways by reading Beowulf and The
Hobbit while listening to Radiohead's Hail to the Thief. To kill a dragon
(i.e. Serpent, Smaug, Wolf at the Door) you need 12 (disciples/dwarves)
plus one thief (burglar, Hail to the Thief/King/thief in the night),
making Christ/Bilbo the 13th Thief. -- Remy Wilkins
 
M

Mark Space

I'd do:
...
Yes, it uses an unchecked cast - but only after the appropriate check
has been done manually. And it doesn't involve allocating anything
except an iterator.

While I can see reasons to use separate methods, my own first
inclination would be to use a refiable type.

SortedSet<myDeal> deals = Collections.checkedSortedSet(
new TreeSet<myDeal>(), myDeal.class );

(There's that old type-token pattern again.)

This builds a set that always must contain the type specified, it
doesn't rely on the user to remember to run some auxiliary method. For
crucial performance reasons, one may not wish to do this. But for
maintainability, the checkedSortedSet method seems preferable to me.
Not only is it more automagic in that it always checks itself, one also
doesn't have to maintain any extra code. The API writers provide the
maintenance for it.
 
T

Tom Anderson

While I can see reasons to use separate methods, my own first inclination
would be to use a refiable type.

SortedSet<myDeal> deals = Collections.checkedSortedSet(
new TreeSet<myDeal>(), myDeal.class );

(There's that old type-token pattern again.)

This builds a set that always must contain the type specified, it
doesn't rely on the user to remember to run some auxiliary method. For
crucial performance reasons, one may not wish to do this. But for
maintainability, the checkedSortedSet method seems preferable to me. Not
only is it more automagic in that it always checks itself, one also
doesn't have to maintain any extra code. The API writers provide the
maintenance for it.

Cool. So how do you get the values into it? Remember, the context here is
the OP's code:

ObjectInputStream si = new ObjectInputStream(new FileInputStream("dealList.treeset"));
SortedSet<myDeal> dealList = (SortedSet<myDeal>)si.readObject();

Effectively, you have a TreeSet containing myDeal instances, in a variable
of type Object - actually a return value, but it comes to much the same
thing. How do you get from that to a filled CheckedSortedSet<myDeal>?

tom

--
The Gospel is enlightened in interesting ways by reading Beowulf and The
Hobbit while listening to Radiohead's Hail to the Thief. To kill a dragon
(i.e. Serpent, Smaug, Wolf at the Door) you need 12 (disciples/dwarves)
plus one thief (burglar, Hail to the Thief/King/thief in the night),
making Christ/Bilbo the 13th Thief. -- Remy Wilkins
 
L

Lew

Tom said:
Cool. So how do you get the values into it? Remember, the context here is
the OP's code:

ObjectInputStream si = new ObjectInputStream(new FileInputStream("dealList.treeset"));
SortedSet<myDeal> dealList = (SortedSet<myDeal>)si.readObject();

Effectively, you have a TreeSet containing myDeal instances, in a variable
of type Object - actually a return value, but it comes to much the same
thing. How do you get from that to a filled CheckedSortedSet<myDeal>?

Something similar to:

SortedSet <MyDeal> deals =
Collections.checkedSortedSet( new TreeSet <MyDeal> (),
MyDeal.class );
deals.addAll( (Collection <?>) si.readObject() );

Since the point of generics is to *prevent* 'ClassCastException', and
the behavior of the 'checkedCollection()' family of methods is to
create a collection that throws that exception if the wrong type
attempts to insert, one still has a small window where the generics
advantage is reduced. The good news is that the locality of the
exception is narrowed to the earliest possible point. Also, that
point is where a cast happens in the source code. This should assist
debugging.
 
W

Wojtek

Lew wrote :
According to the JLS:
Yup.

The Sun naming convention document says:

The examples given in that document are not camel case but all lower
case, for example, "com.apple.quicktime.v2". Notice that they do not
suggest "quickTime".

Being picky, but quicktime could be considered a brand name, and as
such is shown in the same case.
The JLS suggests use of underscores in package names as well.
Yuk!

The official convention is to use whatever local convention one wants
for second and subsequent package name parts, but the first part
should be all lower case. In practice, nearly all package names I've
seen have been all lower-case, but the rules are "less stringent" than
for classes, variables, methods, etc. I find the presence of upper-
case letters in package names rather jarring, being so unexpected and
all, but it's not technically a violation of the convention, nor is
failing to use camel case.

True, though camel case improves readability, which is what we should
strive for anyway.

com.bus.app.retrievestockoptions
vs
com.bus.app.retrieveStockOptions
 
A

Arne Vajhøj

Wojtek said:
Lew wrote :

True, though camel case improves readability, which is what we should
strive for anyway.

com.bus.app.retrievestockoptions
vs
com.bus.app.retrieveStockOptions

I am all with Lew.

package names are always all lowercase.

If suddenly a package name was camel case, then the maintenance
programmer would have to spend the first hour asking people whether
there is any special reason for it.

Arne
 
R

Roedy Green

How can I avoid such warning when compiling my program:

I have wrestled with this problem and finally decided to solve the
problem by avoiding it.

E.g. save an array of E, or E records individually, or use
DataOutputStream. The essential problem is no generics info in
embedded in the ObjectOutputStream. That means you have to cast check
every individual element in the Collection on the way back in. That
means some sort of loop.

This farting around destroys the terseness of ObjectStreams.
--
Roedy Green Canadian Mind Products
http://mindprod.com
PM Steven Harper is fixated on the costs of implementing Kyoto, estimated as high as 1% of GDP.
However, he refuses to consider the costs of not implementing Kyoto which the
famous economist Nicholas Stern estimated at 5 to 20% of GDP
 
L

Lew

Roedy said:
I have wrestled with this problem and finally decided to solve the
problem by avoiding it.

E.g. save an array of E, or E records individually, or use
DataOutputStream. The essential problem is no generics info in
embedded in the ObjectOutputStream. That means you have to cast check
every individual element in the Collection on the way back in. That
means some sort of loop.

This farting around destroys the terseness of ObjectStreams.

Mark Space's suggestion of using 'Collections.checkedSortedSet()' restores
that terseness.
 
W

Wojtek

Arne Vajhøj wrote :
If suddenly a package name was camel case, then the maintenance
programmer would have to spend the first hour asking people whether
there is any special reason for it.

You're kidding right? One hour?

I would think that any competent maintainer could figure this out at a
glance.
 
D

Daniel Pitts

Wojtek said:
Arne Vajhøj wrote :

You're kidding right? One hour?

I would think that any competent maintainer could figure this out at a
glance.
Many maintenance programmers are entry-level and unexperienced. They
either would spend an hour figuring out why it was that way, or just
assume that there is a great reason, and start doing it everywhere else.
Conventions are conventional. Breaking convention requires a reason
and an explanation.
 
L

Lew

Many maintenance programmers are entry-level and unexperienced. They
either would spend an hour figuring out why it was that way, or just
assume that there is a great reason, and start doing it everywhere else.
  Conventions are conventional. Breaking convention requires a reason
and an explanation.

Example:

Eclipse project conventions:
Package names should contain only lowercase ASCII alphanumerics,
and avoid underscore _ or dollar sign $ characters.

Packages: Names should be in lowercase.
<http://www.bejug.org/confluenceBeJUG/display/JJGuidelines/3.+1.+Java+
+Naming+Conventions+Rules>
Package names should contain only lower-case letters.
<http://jaffa.sourceforge.net/documentation/standards/
jaffaStructure.html>
Note: All package names in Java should be lower case.
<http://www.interviewjava.com/2008/07/java-coding-standardsnaming-
conventions.html>
Capitals should not be used in the packages names.

The choice of naming conventions can be an enormously controversial issue,
with partisans of each holding theirs to be the best and others to be inferior.
Colloquially, this is said to be a matter of "religion".
<http://open.sabanciuniv.edu/confluence/display/GRAYMOUND/Suggested
+Naming+Conventions>
all package names are written usen [sic] lower case letters
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top