What's wrong with this sentence?

J

JTL.zheng

Hashtable<String, ItemInfo> userCart = (Hashtable<String, ItemInfo>)
session.getAttribute("userCart");

I am using Eclipse

It get a warning:
Type safety: The cast from Object to Hashtable<String,ItemInfo> is
actually checking against the erased type
Hashtable


Hashtable<String, ItemInfo> userCart = (Hashtable)
session.getAttribute("userCart");

still get a warning too:
Type safety: The expression of type Hashtable needs unchecked
conversion to conform to
Hashtable<String,ItemInfo>

what's wrong with this sentence?
how can I fix it?

Thank you very much in advance.
 
C

cool_guy

The intention behind using generics is to avoid surprises for the JVM.
i.e., You should use generics to avoid runtime(class cast) exceptions.
So in this case you are ought to get this warning in eclipse. There is
nothing wrong in type casting as well, as you are sure that the
attribute you are getting is what you have set before. Well, you can
avoid this warning by implementing Map interface and having something
like this:-

class ItemInfoMap extends HashMap<String,ItemInfo> implements
Map<String,ItemInfo>{
public ItemInfoMap put(String key, ItemInfo value) {
return super.put(key, value);
}
public ItemInfoMap get(String key) {
return super.get(key, value);
}

}


Now Use ItemInfoMap instead of Map :)

ItemInfoMap userCart = (ItemInfoMap)
session.getAttribute("userCart");

Hope this helps!





Thanks!
 
L

Lew

cool_guy wrote:

Please do not top-post. Use trim-and-inline posting.
The intention behind using generics is to avoid surprises for the JVM.

It's to avoid surprises for the programmer, I should say.
i.e., You should use generics to avoid runtime(class cast) exceptions.
Well, you can
avoid this warning by implementing Map interface and having something

Not really a good idea.


Do you need the synchronization that Hashtable provides? Even if you do,
making a synchronizedMap off HashMap is likely a better choice, if not just
use HashMap.

This is a Java issue, not an Eclipse issue.

Welcome to type erasure. Generic casts just don't work unless you suppress
the warning. At run time there is no generic information, so the cast is
"raw" anyway. An attempt to cast a raw type but assign to a generic type
makes the compiler cough. It's what people don't like about Java generics,
and there are proposals afoot to use "reified generics", i.e., generics that
work at run time.

Instead of implementing the cart as a Map, implement it as a custom type that
contains a Map. (Make sure it implements java.io.Serializable.) Change the
session object retrieval to

ShoppingCart userCart = (ShoppingCart) session.getAttribute( "userCart" );
 
R

Roedy Green

What happens when you cast it to a generic like this:

--

oops. In DSK Ctrl-W to send is right next to Ctrl-V to paste. It sent
this off before it was ready.
 
R

Roedy Green

What happens when you cast it to a generic like this:

HashMap<String, ItemInfo> userCart = (HashMap<String, ItemInfo>)
session.getAttribute("userCart");
 
Z

Zig

Hashtable<String, ItemInfo> userCart = (Hashtable<String, ItemInfo>)
session.getAttribute("userCart");

I am using Eclipse

It get a warning:
Type safety: The cast from Object to Hashtable<String,ItemInfo> is
actually checking against the erased type
Hashtable

Ultimately, generics are erased, and this compiles down to

Hashtable userCart = (Hashtable) session.getAttribute("userCart");

You get the warning, since the runtime will only cast your
"session.getAttribute" to Hashtable, and can not verify the contents of
the table. Thus, a subsequent call to

ItemInfo info=userCart.getValue("somevalue");

*could* spuriously throw a ClassCastException (since the cast to ItemInfo
is automatically generated by the compiler).
Hashtable<String, ItemInfo> userCart = (Hashtable)
session.getAttribute("userCart");

still get a warning too:
Type safety: The expression of type Hashtable needs unchecked
conversion to conform to
Hashtable<String,ItemInfo>

what's wrong with this sentence?
how can I fix it?

Some other posters have commented on using a Map instead of Hashtable. It
would be a good idea, when map is initially created, to use
Collections.checkedMap - which will ensure that the contents are what you
expect.

Map<String, ItemInfo> cart=Collections.checkedMap(
Collections.synchronizedMap(new HashMap()),
String.class,
ItemInfo.class));

Now, you can safely assume that the contents of your map are always
String, ItemInfo. The compiler will still generate the same warning, which
you can now safely turn off by decorating the calling method with

@SuppressWarnings("unchecked")

Note that this turns off all unchecked cast warnings in that method, so do
make sure that you have taken reasonable precautions to externally protect
your data before turning off the warning.

HTH,

-Zig
 
J

JTL.zheng

Thanks very much for all of you.

I am using cool_guy's way which define a new class.

Roedy Green's
HashMap<String, ItemInfo> userCart = (HashMap<String, ItemInfo>)
session.getAttribute("userCart");
it still get a warning:

Zig's
Map<String, ItemInfo> cart=Collections.checkedMap(
Collections.synchronizedMap(new HashMap()),
String.class,
ItemInfo.class));

eclipse change it to:

Map<String, ItemInfo> cart = Collections.checkedMap(Collections
.synchronizedMap(new HashMap<String, ItemInfo>()), String.class,
ItemInfo.class);


Thanks again.
:
 

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

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top