Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

Overloaded Methods called with null

Thread view: 
Oliver Brausch - 27 Dec 2005 01:24 GMT
Hello,
I would have to decompile some java code and the decompiler yields:

void a1(C1 c1) {
...
}

void a1(C2 c2) {
...
}

void a1() {
this.a1(null);
}

This can't be correct! Of course this is not possible. E.g.
this.a1((C1)null); would be correct! But how do I know if C1 or C2? The
Decompiler has not done this well! But the problem is that all
decompilers do this error!

Who knows what to do now?
Michael Redlich - 27 Dec 2005 02:57 GMT
> void a1() {
>  this.a1(null);
[quoted text clipped - 6 lines]
>
> Who knows what to do now?

Decompiling is obviously not a trivial task.  The Java decompilers are
all different, and none of them decompile with total accuracy.  It is
quite possible that you may be trying to decompile class files that
have been obfuscated.  Have you tried to decompile class files (such as
your own) that you know for sure haven't been obfuscated?

Which decompiler(s) are you using?  I have experimented with Cavaj
(http://www.bysoft.se/sureshot/cavaj/) and JODE
(http://jode.sourceforge.net/).

For more information about decompiling and obfuscating, check out a
great article written by Greg Travis at
http://www-128.ibm.com/developerworks/java/library/j-obfus/.

Mike.
Roedy Green - 27 Dec 2005 03:36 GMT
>This can't be correct! Of course this is not possible. E.g.
>this.a1((C1)null); would be correct!

You can't cast null to a type.  Null is  already is permitted for
every type. The decompiler is not showing you the full names of the
methods with signatures.

Perhaps a different disassembler would make it clear what is
happening, or look at the hex bytes codes directly.
see http://mindprod.com/jgloss/disassembler.

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Stefan Ram - 27 Dec 2005 03:55 GMT
>You can't cast null to a type.

     "The null reference can always be cast to any reference type."

   The Java Language Specification, Third Edition, 4.1
Oliver Brausch - 27 Dec 2005 09:40 GMT
> >You can't cast null to a type.
>
>       "The null reference can always be cast to any reference type."
>
>     The Java Language Specification, Third Edition, 4.1

Of course you can cast null. And I have found a switch that the
decompiler does it.
Roedy Green - 27 Dec 2005 10:11 GMT
>Of course you can cast null. And I have found a switch that the
>decompiler does it.

I doubt though that, if you looked with Javap -c,  you will ever find
null being cast. It does not do anything. You may cast a null
reference, but not the null literal.

If you did, it could be removed by an optimiser.

I think what you are seeing is just an artifact of the decompiler to
let you know which alternate overload it is using. There is likely not
actually a checkcast instruction.

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Roedy Green - 27 Dec 2005 09:54 GMT
>      "The null reference can always be cast to any reference type."

It still is just a null though isn't it?  Null does not have a type.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Stefan Ram - 27 Dec 2005 15:13 GMT
>>"The null reference can always be cast to any reference type."
>It still is just a null though isn't it?  Null does not have a type.

 In Java, expressions might have a "type".

 An expression is not a value. It is an entity of the source
 code model. For a variable of a reference type »A« the
 expression

( B )a

 has the type »B« (assuming that there is such a relation
 between the type »A« and the type »B«, that such a cast is
 permissible). The expression »( B )a« has this type, and this
 assertion can be made at write time. There is no need to run
 the program to find the type of an expression. The expression
 »( B )a« has this type regardless of whether the reference
 variable »a« contains the value »null« or not.

 The same holds for the type of the expression »( B )null«.

 So, while you are right in so far as the /value/ null indeed
 might not have a type (a value being an entity of the run-time
 model), the expression »( B )null«, which is an entity of the
 source-code model, has a type in Java.

 I also believe that as a value "null" does not have a type.
 In physics, »1 m« (meter) is not »1 s« (second), but by the
 meaning of the mathematical »0« the assertion »0 m = 0 s«
 should be true, because both sides are just »0«.
 
Stefan Ram - 27 Dec 2005 15:51 GMT
>In Java, expressions might have a "type".

 PS:

 I would like to add two remarks:

 One might want to distinguish between the "expression »null«"
 and the "value »null«".

 The term "cast" always refers to expression, one can not cast
 references or objects in Java. So, what the JLS refers to is
 not that one can change the type of the value »null«, but that
 the expression »( A)null« is permissible for a reference type
 »A« and has the type »A«.
Chris Smith - 27 Dec 2005 15:50 GMT
> >      "The null reference can always be cast to any reference type."
>
> It still is just a null though isn't it?  Null does not have a type.

Roedy, you're confusing type and class.  Objects have class, and
references have type.

The null reference certainly does have a type.  It's called "the null
type", and there are widening conversions available from the null type
to all other reference types.  If you cast explicitly to a reference
type, it's generally to remove ambiguity about which of several types
you'd like to match.  This is useful in resolving method overloads.

As for your question, yes it is still just null.  The value doesn't
change; only the type does.  Dereferencing it will yield a
NullPointerException as usual.  Because it doesn't point to an object,
you can't intelligently talk about the *class* of the object it points
to.

Basically, casting null to MyType is equivalent to:

   MyType tmp1 = null;
   someMethod(tmp1);

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Stefan Ram - 27 Dec 2005 16:28 GMT
>Objects have class

 The JLS3 seems to regard the class of an object as its type,
 for example:

     "New objects of the types Boolean, Byte, Short, Character,
     Integer, Long, Float and Double may be implicitly created
     by boxing conversion", JLS3, 4.3.1

>references have type.

 Expressions and objects have types, while references are
 typeless pointers.

 For example,

final java.io.InputStream alpha = System.in;

 binds the variable "alpha" of type Typ "java.io.InputStream"
 to a reference to an object of type
 type "java.io.BufferedInputStream".

 So while the variable and the object both have a type,
 albeit not the same, just the reference does not have
 a type.

    name       binding     Referenz    reference   object
    alpha -------------------> # ------------------> O
java.io.InputStream                 java.io.BufferedInputStream

 Don't be mislead by the term "reference type". This does not
 mean "type of a reference", but it is a type of a variable or
 name that might denote a reference.

>The null reference certainly does have a type.  It's called "the null
>type",

 This is the type of the /expression/ »null«, not of its value.

     "A null literal is always of the null type.", JLS3, 3.10.7

 A »literal« is an entity of the source-code model, not of the
 runtime model.

 More directly my above assertion is confirmed in:

     "There is also a special null type, the type of the
     expression null", JL3, 4.1

 The wording used is "of the /expression/ null". An
 "expression" is an entity of the source code model, not a
 value of the runtime model. The null type is not the type of
 the value »null«, but the type of the expression »null«.
Roedy Green - 28 Dec 2005 08:03 GMT
>  binds the variable "alpha" of type Typ "java.io.InputStream"
>  to a reference to an object of type
[quoted text clipped - 3 lines]
>  albeit not the same, just the reference does not have
>  a type.

This may be edging toward angels dancing on the head of a pin, but at
the JVM level the reference value itself is just an address or pointer
without type information.  However, at the language level the
reference variable obviously DOES have a type as in your example
java.io.BufferedInputStream, and that type will be the name of some
class.  So, at least informally, reference variables have a class.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

ricky.clarkson@gmail.com - 29 Dec 2005 11:45 GMT
As far as I can see, in this discussion there are some terms used in
various ways.  Here's the most granular:

Variable - e.g., List x; It has a type, and its value is a reference
(or a primitive value).
Reference - the value of a variable (or expression) whose type is not
primitive - simply a pointer to a memory address, no type.
Object - the actual instance of a class used at runtime.  It has
multiple types, namely that of the class it is an instance of, all the
superclasses and all the interfaces that the class it is an instance of
implements, and all that the superclasses implement.

Roedy seems to be using Variable and Reference as indistinguishable,
which is not uncommon, and is quite convenient.

The null literal is the only permissible expression of the null type.

The null type can be silently or non-silently cast to any other type,
and the JLS dictates that given a choice between silently casting null
to one of two types, X and Y, if Y is a subtype of X, then Y is chosen.

So you might find yourself needing to do method((String)null) instead
of just method(null) to prevent ambiguous method call compile errors.

However, there is no need to even use the null keyword, except to
safeguard against broken code. [1]

[1]
http://en.wikibooks.org/wiki/Java_Programming/Preventing_NullPointerException
Chris Smith - 29 Dec 2005 16:45 GMT
> However, there is no need to even use the null keyword, except to
> safeguard against broken code. [1]
>
> [1]
> http://en.wikibooks.org/wiki/Java_Programming/Preventing_NullPointerException

That page must be some kind of joke.

The example code for avoiding null on that page doesn't even compile,
and if it were modified in a straight-forward way so that it did
compile, it wouldn't do the same thing as the original.

More to the point, the null value exists because it's helpful.  The
techniques on that page make it exceedingly difficult to accomplish some
very basic tasks, and don't actually lead to safer programming.  Is it
somehow more likely that you'll check a boolean flag rather than that
you'll check for a null value?  Is it now considered acceptable to
modify a public interface to be less capable, just to adopt some wacko
idea of programming form?  And you're now not allowed to create arrays
of any length that's not known at compile-time?  Wow, these people must
like making their lives difficult.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

ricky.clarkson@gmail.com - 29 Dec 2005 19:30 GMT
Chris Smith,

> That page must be some kind of joke.

More of a bin for some ideas I had late one night.  I've modified the
code sample at the top and I think it is more accurate now.

> Is it now considered acceptable to
> modify a public interface to be less capable

That depends.  The rules are not for general programming, per se, but
for avoiding NullPointerExceptions.  New programmers find the
NullPointerException quite obtuse, and are used to error messages at
runtime being not their fault, from the rubbish software that they use
daily.  This isn't conjecture, this is my observation.

> And you're now not allowed to create arrays
> of any length that's not known at compile-time?

Again, if you're interested in preventing NullPointerExceptions, then
this is a rule worth following.  An ArrayList is much better at
ensuring that you don't access the null elements, and you can even
create an array from one anyway.

As well as new learners, these rules may be worth following if you
don't do enough interactive testing before deployment, or if you have
system or safety-critical systems.  I don't know, I haven't evaluated
them.

But they do prevent NullPointerExceptions, so they fulfill the title of
the page.
John C. Bollinger - 30 Dec 2005 04:20 GMT
> Chris Smith,
>
[quoted text clipped - 11 lines]
> runtime being not their fault, from the rubbish software that they use
> daily.  This isn't conjecture, this is my observation.

Where are all these faultless new programmers coming from?  Many moons
ago when I was a new programmer, I tended to think that any error
message at runtime was *surely* my fault.  Perhaps I'm strange that way,
but doesn't it stand to reason that if I don't know very well what I'm
doing then problems are more likely to arise from me not doing it
correctly than from any other source?  For that matter, I'm still the
most likely cause of runtime errors in my programs, even now that I
mostly do know what I'm doing.

NullPointerExceptions are obtuse to the Java newbie, I agree, but the
solution is to educate him about the cause, not to saddle him with a
bunch of code-convoluting rules.  Those given in the Wikibooks article
aren't even 100% reliable.  (Nulls can enter the program through various
methods' return values, for instance.  Also, though its obvious, if one
doesn't want to see NPEs then one shouldn't explicitly throw any.)  What
is the value of teaching rules that are not suitable for general
programming?

I think the article is focused incorrectly.  Rather than presenting
coding rules that are likely to be at least as opaque as the NPEs
themselves, why not explicitly educate about where null values come
from?  That's where all your rules seem to have come from anyway.

>>And you're now not allowed to create arrays
>>of any length that's not known at compile-time?
>
> Again, if you're interested in preventing NullPointerExceptions, then
> this is a rule worth following.

I disagree, but I do find the comment to representative of the article's
 approach.  The problem is not with using arrays in general, nor with
creating them via the "new Type[count]" syntax.  It is with attempting
to dereference an array element that has not been assigned a non-null
value.  Using Lists instead of arrays and initializing arrays with
explicit initializers do reduce the chance of NPEs vs. "new
Type[count]", but sometimes neither of the former gives you what you
want.  A better rule here would be "Initialize All Array Elements",
where you could discuss that the elements are initialized to
null if no array initializer is used.  "Consider using Lists instead of
Arrays" would be potentially useful as a separate rule.

Signature

John Bollinger
jobollin@indiana.edu

Roedy Green - 28 Dec 2005 01:35 GMT
>Roedy, you're confusing type and class.  Objects have class, and
>references have type.

I am thinking in terms of the JVM.  You are thinking in terms of the
JLS.   References have an associated class too, that's how you declare
them.  I am well aware the reference can be null or can point to an
object a subclass of the one mentioned in the declaration.


Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Chris Smith - 28 Dec 2005 07:38 GMT
> I am thinking in terms of the JVM.  You are thinking in terms of the
> JLS.

In that case, references have a set of known facts about the class of
any object they point to... a set that grows larger, for example, with
checkcast bytecodes.  Nevertheless, the fact remains that this knowledge
about the class of any object the reference points to functions as a
type, and is distinct from the class of the object (though it does
constrain the latter).

When you cast null to a type, the resulting checkcast bytecode
instruction inserted into the method causes the VM verifier to acquire
knowledge about the type, which can be used to verify later access to
class members through that reference.

Of course, the overload resolution happens in the source compiler, so
the cast also affects that in a way that predates the existence of
bytecode.

> References have an associated class too, that's how you declare
> them.

Pick your terminology.  Typically, the type of a reference (which is a
class name when written in source code) is called "type", and often
distinguished from "class".

> I am well aware the reference can be null or can point to an
> object a subclass of the one mentioned in the declaration.

Yet you asked about the effect of a cast of the null literal?  There
must be something you're not well aware of.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Oliver Brausch - 27 Dec 2005 20:48 GMT
> It still is just a null though isn't it?  Null does not have a type.

Nobody answers and explains the stuff to him?
Just a hint: a casting sometimes shows the way....
Tim B - 27 Dec 2005 04:35 GMT
> Hello,
> I would have to decompile some java code and the decompiler yields:
[quoted text clipped - 17 lines]
>
> Who knows what to do now?

What can't be correct? If C2 extends C1 or vise versa, this is legal code. I
haven't looked at the language specifications for this, but a bit of
experimenting shows that null is (effectively) cast to the most specific
class possible when there is otherwise an ambiguity.
Chris Smith - 27 Dec 2005 15:52 GMT
> Hello,
> I would have to decompile some java code and the decompiler yields:
[quoted text clipped - 12 lines]
>
> This can't be correct!

What is the relationship between the types C1 and C2?  If one of them is
"maximally specific" then this is perfectly legal, and the method call
will match the maximally specific type.

For example:

   class C1 { }
   class C2 extends C1 { }

The code above is now legal, and the method call will reach the C2
overload.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation



Free Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.