Notes About Java Part Two

Reasons to note minor differences in programming languages

Comments about passing by value

I made some comments about Java passing by value. It does not always pass by value. Those comments are stuckthrough below.

Memory addresses and the == Boolean operator

In Java string literals e.g. (String s1 = “hi” and String s2 = “hi”) when compared with == are identical. However, this identity is derived from their memory address not the content of the string. So, String s1 = “hi” and String s3 = new String(“hi”) when compared s1 == s3 are not equal, but the previous example is equal. The ’new’ call in the second example creates a different String object than the s1 =“hi” literal object. Java must be storing string literals once. This might be an interesting way to get around passing by value in Java but would be working against the intentions of the language.

NaN (Not a Number)

Java allows numbers to be initalized to NaN as a special value that is not null, but is also not a number. isNaN() checks for the NaN state. NaN ALWAYS evaluates to false. Even NaN == NaN is false. null is not used for this purpose. I assume this is to allow for null object comparisons that provide different meanings from unitialized number comparisons. So, Double aNumber = Double.NaN, Double nullNumber = null, and Double anotherNullNumber = null:

public class testNullComp {
  public static void main (String args[]) {
    Double aNumber = Double.NaN;
    Double nullNumber = null;
    Double anotherNullNumber = null;
    if (aNumber == nullNumber) {
      System.out.println("NaN == null");
    } else {
      System.out.println("NaN != null");
    }   

    if (nullNumber == anotherNullNumber) {
      System.out.println("null Double == null Double");
    } else {
      System.out.println("null Double != null Double");
    }   
  }
}  

In Java this allows a null Double to have different meaning than a Double that is NaN, which provides more options when returning values or controlling flow.

Implicit type conversion

Java implicitly casts to higher percision numeric types. At this point, as far as I know, it will not implicitly cast in any way that loses percision.

public class noImplictCastThatLoosesPrecision {
  public static void main (String args[]) {

    int aValue = 25;
    long aLongerValue = 2000000000;

    //allowed
    aLongerValue = aValue;

    //not allowed
    aValue = aLongerValue;
  }
}

This code will throw a complie time error when aValue is assigned the value at aLongerValue. Explicit casting can be done with the following:

public class noImplictCastThatLoosesPrecisionAndExplicitCast {
  public static void main (String args[]) {

    int aValue = 25;
    long aLongerValue = 2000000000;

    //allowed
    aLongerValue = aValue;

    //allowed with explicit cast
    aValue = (int) aLongerValue;
  }
}

This conforms with my understanding of what Java is trying to do with its focus on passing by value. The language is designed to produce as few side effects as possible by requiring coders to be conscious of the choices they are making.

Another language choice that promotes conscious choices

The conversion of Strings to numbers is another method Java employs to encourage conscious choices.

My intution told me that the String class would have a .toDouble() method, .toInt() method, etc. However, this is not the case. Instead, each numeric class has a parse* method that converts a String to the relevant numeric class.

Double numberFromString.parseDouble("2222.022323")

By excluding the conversion of Strings to numbers from the String class and adding it to each individual numeric class, Java makes the programmer choose the type of value to convert to both with strict typing and through method choice.

A quick note about the += operator

Java’s += operator will work with Strings as well as numbers.

String aString = "program";
aString += "ming"

Equals programming.

A note not so much about Java

I have learned that Java is a free-form language. I have used these before, but I had no idea about them. In particular this means the traditional if else construct is a syntactical arrangement of multiple if statements not a special syntax of a single if statement.

The following:

if (var1 == var2) {
  //do the thing
} else if (var2 == var3) {
  //do the other thing
} else {
  //do something else
}

Is the same as:

if (var1 == var2) {
  //do the thing
} else {
  if (var2 == var3) {
    //do the other thing
  } else {
    //do something else
  }
}

The difference being, the nested if is not contained within a block in the first example. Using the second form will have different scope implications than the first.