Java Forum / Virtual Machine / February 2004
checkcast
Dasch - 14 Feb 2004 11:11 GMT Hi,
I have a small question about the checkcast operator.
When I have to translate this kind of Java expression: (String) a
Supposing a is on top of the stack, I will get the following bytecode: checkcast Ljava/lang/String;
My question is, when is it not mandatory to add this checkcast ?
For example:
String a,b; a = (String) b;
In this case, even if the Java source code contained a (String) cast, I don't need to do the checkcast in the resulting bytecode.
Another example where checkcast is now mandatory would be the following. java.util.Hashtable h = new Hashtable(); h.put("e","e"); String a = (String) h.get("e");
So, could you help me (or point me to a resource which explains that in great details) identifying all the cases when checkcast is not necessary ?
Thanks in advance, Dasch.
Boudewijn Dijkstra - 14 Feb 2004 13:03 GMT > Hi, > [quoted text clipped - 24 lines] > great details) identifying all the cases when checkcast is not necessary > ? Read the JVM Specification, par. 2.6 http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html and the Java Language Specification, par. 5.5 http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#20232
chris - 15 Feb 2004 23:18 GMT >> Hi, >> [quoted text clipped - 28 lines] > http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html > and the Java Language Specification, par. 5.5 http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#20232
Yes, but have a look at Staerk, Schmid & Boerger's book : they try to fil in the gaps in Sun's spec. http://www.inf.ethz.ch/~jbook/
 Signature Chris Gray chris@kiffer.eunet.be /k/ Embedded Java Solutions
Chris Uppal - 14 Feb 2004 13:51 GMT > So, could you help me (or point me to a resource which explains that in > great details) identifying all the cases when checkcast is not necessary > ? It's a matter of working out what is necessary in order to satisfy classfile verification.
Unfortunately Sun didn't bother *specifying* verification, they just described the algorithm that their implementation happens to use -- which is not so very useful.
However, and as far as I know (I'm not very up on verification), the main requirement is to ensure that when you use a member of a class, someClass.someName, that the object is known by the verifier to be a someClass (or a subclass). The verifier will "know" that it is a someClass if: - it can deduce that the object came from somewhere (a parameter, method return, field read, etc) with that type or a subtype. - you have reassured it that the object is of the correct type (or a subtype) by interposing a checkcast. Similar observations apply to array access bytecodes.
The details of how it can "deduce that the object came from somewhere" are embedded in the verification non-specification. I wish you joy of it ;-)
In practise, I just tend to assume that the checkcast is necessary exactly when a cast would be necessary in Java. I doubt whether that's precisely true, but it's worked for me so far. Of, course I realise that isn't answering your question...
-- chris
glen herrmannsfeldt - 14 Feb 2004 19:15 GMT Dasch wrote:
(snip about class cast)
> Unfortunately Sun didn't bother *specifying* verification, they just described > the algorithm that their implementation happens to use -- which is not so very > useful. Well, for applications you can run with the verifier off. I presume it will then die on a class cast error, instead of doing the class cast exception.
(snip)
> In practise, I just tend to assume that the checkcast is necessary exactly when > a cast would be necessary in Java. I doubt whether that's precisely true, but > it's worked for me so far. Of, course I realise that isn't answering your > question... If you are casting to a subclass it is needed. If you are casting to the same class (as his example), or, I think, to a superclass, it isn't.
-- glen
Dasch - 17 Feb 2004 17:59 GMT Thanks to all of you :)
> Dasch wrote: > [quoted text clipped - 24 lines] > > -- glen Dasch - 18 Feb 2004 17:08 GMT snipped some
> In practise, I just tend to assume that the checkcast is necessary exactly when > a cast would be necessary in Java. I doubt whether that's precisely true, but > it's worked for me so far. Of, course I realise that isn't answering your > question... > > -- chris Unfortunately (for me), this isn't true. Here's an example of a Cast needed in Java and not needed by the JVM (don't ask me why):
Object o = new String(111); ((String)o).charAt(1);
If you remove the checkcast generated by javac, (and you recompile the class), it will run without any trouble.
But, I suppose it will be safer (and easier) for me to assume that when you need a Cast in java, you should better use a corresponding checkcast.
Dasch
Chris Uppal - 18 Feb 2004 18:49 GMT > Unfortunately (for me), this isn't true. Here's an example of a Cast > needed in Java and not needed by the JVM (don't ask me why): > > Object o = new String(111); > ((String)o).charAt(1); Try rephrasing it more how the verifier would see it -- without explicit type declaration, but with (restricted) knowledge of where things came from. It may make more sense then:
o <which must now be a String> = new String(111); o <which must still be a String>.charAt(1);
Incidentally, and as far as I know*, the verifier is not supposed to verify that the member actually exists, only that the object is of (a subclass of) the class that is mentioned in the method call, or field access, bytecode. So if we write:
String str = new String(); str.charAt(int);
then the verfier is only interested in proving that the "str" on the second line must in fact be a java.lang.String, it doesn't care whether there is any such method as java.lang.String.charAt(int).
[*] I'd very much welcome correction, clarification, or confirmation on this.
-- chris
glen herrmannsfeldt - 23 Feb 2004 01:14 GMT (snip)
> Unfortunately (for me), this isn't true. Here's an example of a Cast > needed in Java and not needed by the JVM (don't ask me why):
> Object o = new String(111); > ((String)o).charAt(1);
> If you remove the checkcast generated by javac, (and you recompile the > class), it will run without any trouble. Well, without the cast how does it know which class charAt is in?
Now, if Object had a charAt method it would invoke that, but it doesn't and you wouldn't want it to, anyway.
What does it do if you use the fully qualified method name?
o.java.lang.String.charAt(1);
(Just to be confusing, note that you are allowed to have class, method, and object reference variables all with the same name, and there are ambiguous cases that Java resolves.)
-- glen
Michael Amling - 25 Feb 2004 15:04 GMT > (snip) > >> Unfortunately (for me), this isn't true. Here's an example of a Cast >> needed in Java and not needed by the JVM (don't ask me why): > >> Object o = new String(111); What String constructor is this? AFAIK, String has never had a constructor that just takes an int parameter.
>> ((String)o).charAt(1); > [quoted text clipped - 9 lines] > > o.java.lang.String.charAt(1); When would this ever work? 'No field named "java" was found in type "java.lang.Object"'
> (Just to be confusing, note that you are allowed to have class, > method, and object reference variables all with the same name, > and there are ambiguous cases that Java resolves.) --Mike Amling
Dasch - 26 Feb 2004 12:29 GMT >>>> Object o = new String(111); >> >> What String constructor is this? AFAIK, String has never had a >> constructor that just takes an int parameter. That was a typo ! I meant:
Object o = new String("111")
>> (snip)
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|