Sunday, 27 November 2005

Changing Java: Adding simpler primitive creation

So, when you're coding in Java sometimes you just have to use primitives. (We'd all love to use objects all the time, but that just isn't possible in Java). However creating primitives can be a pain on occasion, so what could we do?

Defining a variable/constant is easy and just works for short/byte (and all types):

// defining variables is easy:
double val1 = 2.1d;
float val1 = 2.1f;
long val1 = 2L;
int val1 = 2;
short val1 = 2;
byte val1 = 2;

However calling a method shows us the nasty difference between bytes and shorts compared to longs, floats and doubles:

someFloatMethod(2f);  // compiles OK
someShortMethod(2);   // doesn't compile
someByteMethod(2);    // doesn't compile
someShortMethod((short) 2);  // compiles OK
someByteMethod((byte) 2);    // compiles OK

public void someFloatMethod(float f) {
}
public void someShortMethod(short s) {
}
public void someByteMethod(byte b) {
}

So why do we not have a convenient shorthand for bytes and shorts like the 'f' for float or 'd' for double?

someShortMethod(2s);  // note the 's'
someByteMethod(2b);   // note the 'b'

public void someShortMethod(short s) {
}
public void someByteMethod(byte b) {
}

A related issue is creating a binary value (which I needed to do tonight - bonus points if you can guess the pattern I was storing!):

int binary =
    (1 << 2) + (1 << 5) + (1 << 7) + (1 << 10) +
    (1 << 13) + (1 << 16) + (1 << 18) + (1 << 21) +
    (1 << 24) + (1 << 26) + (1 << 29);

Yuck! Why could I not create it with a specialist syntax like this:

int binary = 0b00100101:00100101:00100100:10100100;

While not suitable for every case that you want to create a binary value, it definitely has value. The question is whether its too minor a use case to justify a language change?

5 comments:

  1. It is legal to write "short val1 = 2;" and "byte val1 = 2;", you don't need to cast them.

    JLS 5.2 : http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.2

    The compile-time narrowing of constants means that code such as:

    byte theAnswer = 42;

    is allowed. Without the narrowing, the fact that the integer literal 42 has type int would mean that a cast to byte would be required:

    byte theAnswer = (byte)42; // cast is permitted but not required

    ReplyDelete
  2. Stephen Colebourne26 November 2005 at 22:51

    Thanks JiaYun, I've rewritten the article to clarify the problem.

    ReplyDelete
  3. I think there's a typo there:
    someByteMethod((byte 2));

    I guess you mean:
    someByteMethod((byte) 2);

    ReplyDelete
  4. Patrick Gotthardt27 November 2005 at 12:06

    The binary-thing could also be done like this:
    int binary = Integer.parseInt("1001010", 2);

    Isn't such a big deal at all (at least it is far more readable), though I'd as well prefer doing this without a new String-object.

    0b1001010 would seem to be a valid choice when you remember 0xFFF or something like that.

    ReplyDelete
  5. Norman H. Azadian30 November 2005 at 10:05

    For the binary thing, why not just use 0x252524a4? Standard, compact, easy to read and understand, and doesn't require yet another extension to the language.

    ReplyDelete