Home | JSP | EJB | JDBC | Java Servlets | WAP  | Free JSP Hosting  | Spring Framework | Web Services | BioInformatics | Java Server Faces | Jboss 3.0 tutorial | Hibernate 3.0 | XML

Tutorial Categories: Ajax | Articles | JSP | Bioinformatics | Database | Free Books | Hibernate | J2EE | J2ME | Java | JavaScript | JDBC | JMS | Linux | MS Technology | PHP | RMI | Web-Services | Servlets | Struts | UML


 

Search Host

Monthly Fee($)
Disk Space (MB)
Register With us for Newsletter!
Visit Forum! Post Questions!
Jobs At RoseIndia.net!

Have tutorials?
Add your tutorial to our Java Resource and get tons of hits.

We offer free hosting for your tutorials. and exposure for thousands of readers. drop a mail
roseindia_net@yahoo.com
 
   

Tutorials

Java Server Pages

JAXB

Java Beans

JDBC

MySQL

Java Servlets

Struts

Bioinformatics

Java Code Examples

Interview Questions

 
Join For Newsletter

Powered by groups.yahoo.com
Visit Group! Post Questions!

Web Promotion

Web Submission

Submit Sites

Manual Submission?

Web Promotion Guide

Hosting Companies

Web Hosting Guide

Web Hosting

Linux

Beginner Guide to Linux Server

Frameworks

Persistence Framework

Web Frameworks

Free EAI Tools

Web Servers

Aspect Oriented Programming

Free Proxy Servers

Softwares

Adware & Spyware Remover

Open Source Softwares

Treating Types Equally

       

2003-04-29 The Java Specialists' Newsletter [Issue 069] - Treating Types Equally - or - Life's Not Fair!

Author: Dr. Heinz M. Kabutz

If you are reading this, and have not subscribed, please consider doing it now by going to our subscribe page. You can subscribe either via email or RSS.


Welcome to the 69th edition of The Java(tm) Specialists' Newsletter. After my last newsletter, the listserver told me that quite a few of you did not receive the newsletter. If you are reading this on the internet, and you did not receive this newsletter, be warned - you have probably been deleted from the list! We now have approximately 5593 working email addresses.

Why can we not treat everyone equally? A few weeks ago, my four year old son Maximilian wanted to know the answer to that age-old question. Maxi's 3 year old cousin was visiting and was allowed to stay up and watch cartoons on TV, whilst he had to go to bed to sleep. "Sorry, Maxi, but as you will soon find out: Life is not fair! There is nothing I can do to change that, that is just the way it is."

A well known person (so well known that I have forgotten who it was) once said: "Everyone that I meet is my superior in some way"

This newsletter is about some operations who treat types equally (when perhaps they should not), and others, who due to their own feelings of inadequacy, do not. It all gets rather confusing, as you will soon find out. Remember, if you don't understand this newsletter: Life is not fair! Read the Java VM Spec. Write to the editor of this fine newsletter (editor@dev/null). But don't moan.

I want to thank all those who make the effort to write to me to correct errors in my newsletters. Please continue your good work. It makes the newsletter more useful when we remove the Gremlins.

For those living in Cape Town, South Africa, we are doing another Design Patterns Course in May 2003, please see the advert at the bottom of this newsletter. If you come on that course, you will also receive a free copy of the Java Specialists' Newsletters Book.

Treating Types Equally - or - Life's Not Fair!

What is the purpose of a byte?

Let me ask that question a bit differently: Why would you use a byte, as opposed to an int? To save memory? Only since JDK 1.4.x does a byte field take less memory than an int field. To increase computational speed? Maybe the opcodes for adding bytes are faster than for ints?

Perhaps byte should have been left out of the Java Programming Language? Not just byte, but also short and char? The original Oak specification, on which Java is based, had provision for unsigned integral values, but they did not make it, so why do we have those other types?

Ahh, but a byte[] will take up less space than a char[]. That is true, so they do have a reason to exist! But what about computation?

"Most of the instructions in the Java virtual machine instruction set encode type information about the operations they perform. For instance, the iload instruction loads the contents of a local variable, which must be an int, onto the operand stack. The fload instruction does the same with a float value. The two instructions may have identical implementations, but have distinct opcodes." - VM Spec The Structure of the Java Virtual Machine.

This brings along a slight problem: there are too many types in Java for the instruction set. Java has only one byte per opcode, so there are a maximum of 256 opcodes. There is therefore great pressure to have as few opcodes as possible.

The 18 opcodes that are defined for int, and not for short, char and byte, are: iconst, iload, istore, iinc, iadd, isub, imul, idiv, irem, ineg, ishl, ishr, iushr, iand, ior, ixor, if_icmpOP, ireturn. If these were also defined for the other three primitive types, we would require at least an additional 54 opcodes.


There is only one opcode that is marked as "unused". It is opcode 0xBA. Go figure. Probably the BSc Computer Science nerds having a dig at all the BA's that are unused ;-) Fries with that?


What does that mean for you and me? Let's look at a code snippet, sent to me by Jeremy Meyer. Jeremy helped me get my first job at a company called DataFusion Systems in South Africa, now called DataVoice, and part of a bigger company called Spescom. DataVoice are probably not hiring anyone at the moment, but they are one fine company to work for, so if ever you are offered a job there, take it at any price! Even working there for free would be a bargain, considering what you will learn there. Thanks Jeremy!

public class ByteFoolish {
  public static void main(String[] args) {
    int i = 128;
    byte b = 0;
    b |= i;
    System.out.println("Byte is " + b);
    i = 0;
    i |= b;
    System.out.println("Int is " +i);
  }
}

When we run this, we see the following:

Byte is -128
Int is -128

Here we start with a value bigger than 127 (the maximum positive byte value). We store it in an int, and then OR the bits into the byte.

The first System.out.println statement naturally reports the value of the byte as -128, which one would expect. The byte is, after all, signed and has range -128 to +127. Then we reset the int to 0, and OR the value of the byte back into the int.

The int now has the value of -128!

How could we OR the int with just the bits that belong to the last byte? We could first bitwise AND it with a mask that only shows the last byte and OR the result with the int.

public class ByteFoolish2 {
  public static void main(String[] args) {
    int i = 128;
    byte b = 0;
    b |= i;
    System.out.println("Byte is " + b);
    i = 0;
    i |= (b & 0x000000FF);
    System.out.println("Int is " +i);
  }
}

Now when we run the program, we see:

Byte is -128
Int is 128

Bitwise arithmetic with byte, short and char is challenging. Inside the JVM, these are first translated to ints, worked on, and then converted back to bytes. Let's disassemble the class to make sure that this is what is happening:

public class ByteFoolish3 {
  public ByteFoolish3() {
    int i = 128;
    byte b = 0;
    b |= i;
    i = 0;
    i |= b;
  }
}

We disassemble with javap -c ByteFoolish3 (you know how to do that by now):

 0 aload_0
 1 invokespecial #9 <Method java.lang.Object()>
 4 sipush 128   // push 128 onto stack
 7 istore_1     // store in int register 1
 8 iconst_0     // push constant "0" onto stack
 9 istore_2     // store in int register 2
10 iload_2      // load register 2
11 iload_1      // load register 1
12 ior          // OR them together as ints
13 i2b          // convert the int on the stack to a byte
14 istore_2     // store the value in register 2
15 iconst_0     // push constant "0" onto stack
16 istore_1     // store this in int register 1
17 iload_1      // load register 1
18 iload_2      // load register 2
19 ior          // OR them together
20 istore_1     // store them in register 1
21 return

Is i += n the same as i = i + n ?

I was sitting in a seminar on Refactoring by Martin Fowler a few years ago. The things Martin was saying sounded like music to my ears. I had refactored my code for many years, but had never heard such a thorough approach on the subject. The one thing that stuck in my mind was the difference between i += n and i = i + n.

Would the following compile?

public class Test1 {
  public static void main(String[] args) {
    int i = 128;
    double d = 3.3234123;
    i = i + d;
    System.out.println("i is " + i);
  }
}

The answer is that it would not compile. A double is 64 bits with a very big range. There is no way that it would fit into an int without losing precision. It is not safe to run such code, so when we attempt to compile it, we get the following message:

Test1.java:5: possible loss of precision
found   : double
required: int
    i = i + d;
          ^
1 error

This is good. We pick up errors before we run the program. Ya'll know how to cast a double to an int if you definitely want to do that. You can either cast the values individually before you add, or you can cast the result:

public class Test2 {
  public static void main(String[] args) {
    int i = 128;
    double d = Integer.MAX_VALUE + 12345.33;
    i = i + (int)d;
    System.out.println("i1 is " + i);
    i = 128;
    i = (int)(i + d);
    System.out.println("i2 is " + i);
  }
}

In a way, I would expect both i's to have the same value, but due to the precision loss of doubles, they are not equal:

i1 is -2147483521
i2 is 2147483647

Let's have a look at the next class, Test3:

public class Test3 {
  public static void main(String[] args) {
    int i = 128;
    double d = Integer.MAX_VALUE + 12345.33;
    i += d; // oops, forgot to cast!
    System.out.println("i is " + i);
  }
}

Does this compile? Ooops, we forgot to cast! But, does it compile? Yes it does, and when we run it, we get:

i is 2147483647

Therefore, we can say that i += n is the same as i = (type_of_i)(i + n).

Kind regards, and thanks for the great feedback after the last newsletter!

Heinz


This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information.

       

Useful Links
  JDO Tutorials
  EAI Articles
  Struts Tutorials
  Java Tutorials
  Java Certification
Tell A Friend
Your Friend Name
Search Tutorials

 

 
Browse all Java Tutorials
Java JSP Struts Servlets Hibernate XML
Ajax JDBC EJB MySQL JavaScript JSF
Maven2 Tutorial JEE5 Tutorial Java Threading Tutorial Photoshop Tutorials Linux Technology
Technology Revolutions Eclipse Spring Tutorial Bioinformatics Tutorials Tools SQL
 

Home | JSP | EJB | JDBC | Java Servlets | WAP  | Free JSP Hosting  | Search Engine | News Archive | Jboss 3.0 tutorial | Free Linux CD's | Forum | Blogs

About Us | Advertising On RoseIndia.net

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright 2007. All rights reserved.