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 / January 2007

Tip: Looking for answers? Try searching our database.

Parentheses issue

Thread view: 
jupiter - 31 Dec 2006 01:23 GMT
Hi guys,
Can somebody explain in English why the cast of obj to
AccountBalance works here?

if(obj instanceof AccountBalance &&
  ((AccountBalance)obj).getBalance() == this.balance) {
return true;
}

But doesn't work here?

if(obj instanceof AccountBalance &&
   (AccountBalance)obj.getBalance() == this.balance) {
return true;
}

In the second snippet the compiler complains of "incompatible
operand types, AccountBalance and double" so it is apparently not
even noticing the obj.getBalance() method.  Or maybe it needs to
only weigh the leftmost object versus the right hand operand, and
I've separated or broken up the lefthand operand?  I expected that
the cast would be applied first, making obj a type of
AccountBalance, and then getBalance() would be parsed.

Not true but I don't know why.
Andrew - 31 Dec 2006 01:52 GMT
This is an order of operations issue. It would also help to know
whether the error you got was a compile-time error or a runtime error.
(I'm not sure if you said or not.)

If it was a compile-time error, read this, but you might want to read
it anyway:

Sometimes you can use

    (Type)object

without having to put an extra set of parentheses around the whole
thing, like if you are saying

    Type1 object2 = (Type1)object1;

but since the casting operation happens in the order it does, to do
most other operations on the casted object, you will need another set
of parentheses, like in the following example:

    if(object1 instanceof Type1)
         if(((Type1)object1).booleanFunction())
              doSomething();

Another common case is getting an item out of a list:

    if(list.get(index) instanceof Type1)
         ((Type1)list.get(index)).doSomething();

OTHERWISE, if it was a runtime error, read this (and you might want to
read it anyway):

The && operator evaluates the expressions on both sides. Even if the
first side is false (and therefore it would logically return false
regardless of the second side's value) the second side will still be
evaluated. Thus, in a case such as

    if(object1 instanceof Type1 &&
((Type1)object1).someBooleanFunction())
         doSomething();

the Java Virtual Machine will come across an error if the object is not
of the required type, because it will try to evaluate the second
expression.

The way to solve this is to do either this

    if(object1 instanceof Type1)
         if(((Type1)object1).booleanFunction())
              doSomething();

or, if you are feeling bold and know or are ready to learn the ternary
operator:

    if(object1 instanceof Type1 ? ((Type1)object1).booleanFunction() :
false)
         doSomething();

I hope this helps.
jupiter - 31 Dec 2006 03:58 GMT
> This is an order of operations issue. It would also help to know
> whether the error you got was a compile-time error or a runtime
> error.
> (I'm not sure if you said or not.)

Hi, Andrew, and yes, compile time.

> If it was a compile-time error, read this, but you might want to
> read
[quoted text clipped - 19 lines]
>          if(((Type1)object1).booleanFunction())
>               doSomething();

I guess the "order it does" is last on the to-do list, eh?

> Another common case is getting an item out of a list:
>
>     if(list.get(index) instanceof Type1)
>          ((Type1)list.get(index)).doSomething();

It's good to see this in another form, especially a common one.
The order of execution with cast is something I've never paid much
attention until now.

> OTHERWISE, if it was a runtime error, read this (and you might
> want to
[quoted text clipped - 11 lines]
> ((Type1)object1).someBooleanFunction())
>          doSomething();

So this cast fails at runtime.  Got it.

> the Java Virtual Machine will come across an error if the object
> is not
[quoted text clipped - 6 lines]
>          if(((Type1)object1).booleanFunction())
>               doSomething();

Thanks .... good to know.

> or, if you are feeling bold and know or are ready to learn the
> ternary
[quoted text clipped - 6 lines]
>
> I hope this helps.
Nice, I've never seen ternary used like that.

Thanks Andrew.
Daniel Pitts - 31 Dec 2006 05:59 GMT
> This is an order of operations issue. It would also help to know
> whether the error you got was a compile-time error or a runtime error.
[quoted text clipped - 55 lines]
>
> I hope this helps.

Actually, you are wrong about the &&...  && is a short-circuting
operator, & is not.

<sscce>
public class Test {
   private static boolean aCalled = false;
   private static boolean bCalled = false;

   public static void main(String[] args) {
       if (a() && b()) {
          System.out.println("a() and b() returned true");
       }
       System.out.println("aCalled:" + aCalled + ", bCalled: " +
bCalled);
       aCalled = false;
       bCalled = false;
       if (a() & b()) {
          System.out.println("a() and b() returned true");
       }
       System.out.println("aCalled:" + aCalled + ", bCalled: " +
bCalled);
   }
   public static boolean a() {
       aCalled = true;
       return false;
   }
   public static boolean b() {
       bCalled = true;
       return false;
   }
}
</sscce>

<output>
aCalled:true, bCalled: false
aCalled:true, bCalled: true
</output>

The trouble with the code the OP presented was indeed the compile
error.

(MyType)expression will cast the result of "expression" to MyType,
where as ((MyType)object).member will cast object to MyType, and then
access member.

Hope this helps,
Daniel.
Patrick May - 31 Dec 2006 02:35 GMT
> Can somebody explain in English

    Will you accept geeklish?

> why the cast of obj to
> AccountBalance works here?
[quoted text clipped - 10 lines]
> return true;
> }

    The object member operator ('.') has higher precedence than the
cast operator ('(...)').  The second form tries to call getBalance()
before casting obj to the AccountBalance type.
   
> In the second snippet the compiler complains of "incompatible
> operand types, AccountBalance and double"

    The error message is certainly not descriptive.

Regards,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc.  | Large scale, mission-critical, distributed OO
                      | systems design and implementation.
         pjm@spe.com  | (C++, Java, Common Lisp, Jini, middleware, SOA)
jupiter - 31 Dec 2006 04:01 GMT
>> Can somebody explain in English
>
>     Will you accept geeklish?

Bring it on!

>> why the cast of obj to
>> AccountBalance works here?
[quoted text clipped - 16 lines]
> getBalance()
> before casting obj to the AccountBalance type.

Nice explanation.  Is that actually geekish?  I've heard much
worse, hehe.

>> In the second snippet the compiler complains of "incompatible
>> operand types, AccountBalance and double"
>
>     The error message is certainly not descriptive.

Sorry for the lack of documentation;  it was comparing doubles (or
was supposed to be until the cast failed.)

Thanks, Patrick.
Lew - 31 Dec 2006 14:57 GMT
"jupiter" <jupiter49byebyeSpam@msn.com> writes:
>> if(obj instanceof AccountBalance &&
>>     (AccountBalance)obj.getBalance() == this.balance) {
>> return true;
>> }
>> ... the compiler complains of
>> "incompatible operand types, AccountBalance and double"

>  The error message is certainly not descriptive.

Seems descriptive enough to me. It says that the operands, in this case of ==,
are of incompatible types. The right side is clearly the "double" of the
comparison, so the left side clearly must be the "AccountBalance". This it
clearly is, because the cast makes it so. Therefore, clearly, the operands are
incompatible, just as the error message clearly describes. The message, in
fact, is entirely descriptive. Certainly.

As for the error itself, one should be at least a little bit aware of operator
precedence (*not* "order of operations", which can change), and other Java
language fundamentals, if one is to be a Java programmer. One should be
completely aware that there exist rules of operator precedence, and what the
term means.

That said, it is good practice to use a few extra parentheses to clarify the
order as expressions get more complex, since some of the precedence rules may
be non-obvious even to the experienced.

A closely related topic is operator associativity. What is the interpretation of

a == b? c == d? x : y : e == f? z : null;

just to invent one mildly pathological case. Parentheses would help
readability here, too.

- Lew
John Ersatznom - 04 Jan 2007 16:02 GMT
>     (AccountBalance)obj.getBalance() == this.balance) {
>
> In the second snippet the compiler complains of "incompatible
> operand types, AccountBalance and double

Error on line 17: floating-point type used to record currency data. Your
bank account balance is now reduced by 0.00000325364 cent due to
round-off error. Have a nice day.
jupiter - 06 Jan 2007 04:02 GMT
>>     (AccountBalance)obj.getBalance() == this.balance) {
>>
[quoted text clipped - 4 lines]
> data. Your bank account balance is now reduced by 0.00000325364
> cent due to round-off error. Have a nice day.

I got a slightly different number.  Let's compromise.


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



©2008 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.