Archive for April, 2017

Pushing Java Envelope – Part 4: boolean’s && Boolean’s

23/04/2017

Java has primitive types and reference types. The difference is that, the primitive types are not treated as objects, while reference types are almost always objects. Depending on this, there are many places where strictly reference types are required. For example Collections. When we want to create a list of booleans, we must code as

List<Boolean>

The important part here is the Boolean class. Although our intent is to use the boolean primitive type, Collections directs us to use the Boolean wrapper class. This has important consequences. Somehow, we need to transform primitive types back and forth to the wrapper class. Thankfully, from version 5 and on, Java can do this automatically if certain conditions hold. For other cases, Java presents different constructors and static methods. 

In the case of primitive types, the boolean is very simple. There only exists true and false. The comparison between two boolean values can simply be done by the == binary operator. However, the wrapper class Boolean complicates the issue.

Creating a Boolean

The use of == with primitive boolean type has a very strong influence on using it with Boolean objects. Long time Java developers know that applying == operator for comparing objects should be avoided. However, in the case of Boolean class, there are only two Boolean.TRUE and Boolean.FALSE static objects. It is so tempting to type == in place of equals(). How error-prone can it be to use it for a class that only needs two objects? In fact, it can cause headaches.

When we look at the Boolean class, we see two constructors. One for converting from a boolean value, and one for converting from a String. There is a very important effect of these constructors. As their purpose of existence, they CREATE (or in Java doc terms ALLOCATE) new objects. To see what they really do, I have read the source code. To get those, we must download JDK. In macOS, we can find the Java source codes under

/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/

There is a src.zip file. Java creators make our lives easier by mirroring the package class locations to source files. Therefore, to get the Boolean.java file, we look for java/lang folders. Both of the constructors are like this:

public Boolean(boolean value) {
  this.value = value;
}

public Boolean(String s) {
  this(parseBoolean(s));
}

public static boolean parseBoolean(String s) {
  return ((s != null) && s.equalsIgnoreCase("true"));
}

The String “true” is case insensitive, but any leading or trailing whitespaces make the object FALSE. Also, please do not forget the parseBoolean() method. We will talk about it later on. Let’s make a quick fact check.

public static void main(String[] args) throws Exception {
  Boolean boolTrueOne = new Boolean(true);
  Boolean boolTrueTwo = new Boolean(true);
  if (boolTrueOne == boolTrueTwo) {
    System.out.println("== comparison is true.");
  }
  if (boolTrueOne.equals(boolTrueTwo)) {
    System.out.println("equals() is true.");
  }
}

The naive expectation is:

  • there are two booleans 
  • they are true
  • they are equal
The truth is:
  • there are two Boolean objects
  • their values are true
  • they are different objects, so they are NOT equal

We can verify it with the following output.

bool1

It is exactly the same for the constructor Boolean(String). The case INSENSITIVE input to that constructor will create different objects. Moreover, they are also different than the objects created by the first constructor.

package blog.mertersualp.booleans;

public class BooleanObjectCreations {
  public static void main(String[] args) throws Exception {
    Boolean boolTrueOne = new Boolean(true);
    Boolean boolTrueTwo = new Boolean(true);
    if (boolTrueOne == boolTrueTwo) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOne.equals(boolTrueTwo)) {
      System.out.println("equals() is true.");
    }
    
    Boolean boolTrueOneFromString = new Boolean(“TRue");
    Boolean boolTrueTwoFromString = new Boolean("true");
    if (boolTrueOneFromString == boolTrueTwoFromString) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOneFromString.equals(boolTrueTwoFromString)) {
      System.out.println("equals() is true.");
    }
    
    if (boolTrueOne == boolTrueTwoFromString) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOne.equals(boolTrueTwoFromString)) {
      System.out.println("equals() is true.");
    }
  }
}

bool2

As now we expect, three comparisons made by the == operator all yield to false. Yet, a subtle modification, however, will instantly make all comparisons accepted. 

package blog.mertersualp.booleans;

public class BooleanObjectCreations {

  public static void main(String[] args) throws Exception {
    Boolean boolTrueOne = new Boolean(true);
    Boolean boolTrueTwo = new Boolean(true);
    if (boolTrueOne.booleanValue() == boolTrueTwo) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOne.equals(boolTrueTwo)) {
      System.out.println("equals() is true.");
    }
    
    Boolean boolTrueOneFromString = new Boolean("TRue");
    Boolean boolTrueTwoFromString = new Boolean("true");
    if (boolTrueOneFromString.booleanValue() == boolTrueTwoFromString) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOneFromString.equals(boolTrueTwoFromString)) {
      System.out.println("equals() is true.");
    }
    
    if (boolTrueOne.booleanValue() == boolTrueTwoFromString) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOne.equals(boolTrueTwoFromString)) {
      System.out.println("equals() is true.");
    }
  }
}

bool3

What has changed? The only modification we did is supplying the primitive value of Boolean object that it represents to the left side of the == binary operator. This is done by the method written in bold, booleanValue(). Here is the source code:

public boolean booleanValue() {
  return value;
}

Having a primitive type on the left (or right) of the == binary operator changes the dynamics. Before, == operator simply wants to learn wether its operands are the same objects. It does not look at their values, but only there memory locations. When at least one operator becomes a primitive type, Java implicitly converts the non-primitive (i.e. reference) type into its corresponding primitive type. This is called unboxing. In Java terms, the reference type class is Wrapper class. The boolean primitive type is wrapped by Boolean class. The unboxing is replacing the object with its <primivite type>Value() method. Remember that we explicitly called the booleanValue() method for one operand. Java compiler implicitly makes the very same call for the other operand of ==. Therefore, all these operations reduces to primitive type checking. 

The parseBoolean(String) method may be preferred in place of Boolean(String) constructor. It directly converts the input string into its corresponding primitive boolean value.

Reusing static Booleans

There is another way to handle Boolean objects. At the very beginning of this post, I mentioned Boolean.TRUE and Boolean.FALSE static objects. The Boolean class contain those:

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

These two objects are created when the Boolean class is initialised. From then on, we can always access them. We can also assign them to our declared objects instead of creating new Boolean objects each time. Now, let’s replace object creation with these static fields and remove the booleanValue() methods.

package blog.mertersualp.booleans;

public class BooleanObjectCreations {

  public static void main(String[] args) throws Exception {
    Boolean boolTrueOne = Boolean.valueOf(true);
    Boolean boolTrueTwo = Boolean.valueOf(true);
    if (boolTrueOne == boolTrueTwo) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOne.equals(boolTrueTwo)) {
      System.out.println("equals() is true.");
    }
    
    Boolean boolTrueOneFromString = Boolean.valueOf("TRue");
    Boolean boolTrueTwoFromString = Boolean.valueOf("true");
    if (boolTrueOneFromString == boolTrueTwoFromString) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOneFromString.equals(boolTrueTwoFromString)) {
      System.out.println("equals() is true.");
    }
    
    if (boolTrueOne == boolTrueTwoFromString) {
      System.out.println("== comparison is true.");
    }
    if (boolTrueOne.equals(boolTrueTwoFromString)) {
      System.out.println("equals() is true.");
    }
  }
}
bool4

Here, we only use single one object, which is the static final Boolean TRUE. SO, all comparisons, either object equality or value equality are all true.

Conclusion

What I like about the == operator while dealing with objects is not its comparison ability because it cannot do that properly. Its beauty is that it will teach us the underlying truth of the object’s origin. Is it a brand new object or does it refer to a previously created one? This answer to this question can be found by applying == to both operands.

Frankly, the == operator for objects is mostly used by mistake. Boolean objects inherently encourage this tendency, since they represent true and false. The techniques presented above may decrease the erroneous side effects.

Three take-aways from this study are:

  1. Using Boolean constructors should be avoided if no other way exists. Instead, applying the respective static valueOf() methods should be encouraged.
  2. If somehow Boolean constructors are (or must be) employed and different Boolean objects are created, converting them to primitive boolean values by booleanValue() method is invaluable.
  3. In the very end, we can reiterate an important but easily forgettable Java rule: Use equals() every time when comparing objects, not the == operator.
Advertisements

Pushing Java Envelope – Part 3: Packages & Imports

07/04/2017

The art of coding is in fact deciding on where to put a piece of code. It can be either within a file or distributing it to different files. However, putting code into many files create a few problems. First one is name conflicts. Suppose that there are two java class files containing different classes but having the same name. When we refer to that class, we must uniquely specify which one is our preference. There should be no ambiguity. The second problem is access protection. When we define a class, we may want to preserve its use to only related classes. To solve these problems, Java presents the package mechanism.

Declaring Packages

A class may not be a part of a package but for the reasons above, it is highly recommended to do so. If we do not explicitly declare its package, a class is a member of default package. The packages are generally named by reversing the domain name of the companies. In my case, I am using mertersualp.blog as my URL and reversing it will result blog.mertersualp. Hence, my packages will start with this. The dot is the separator. We cannot use dot in our package names. Actually, the package naming rules are exactly the same with variable naming ones. The package name, or a part just after the separating dot, may start with a letter, underscore(_), or dollar sign($). After that, the numbers may also appear with these characters. A small example file with its package declaration is here:

package blog.mertersualp.imports;

public class ImportTests {
  public static final int LIMIT = 10;
  
  public static void main(String[] args) {
    System.out.println("ImportTests main method is running.");
  }
  
  public int nonStaticMethod() {
    System.out.println("ImportTests nonStaticMethod is running.");
    return 2;
  }
}

In Java, there is a clear distinction between the location of the .java source code and the location of the .class file. The .java source code file can be anywhere in the file system. It is only used while compiling. However, the important part is the location of the .class file. To be used properly, it must be “somewhere” under the java class path. In any operating system, we can set the system CLASSPATH variable with one or more file system locations. Another method is providing the preferred path as the class path by using the -cp parameter while compiling the source codes. If we do not explicitly define it, the default class path will be the current directory. Let’s see what happens when the code above is compiled simply with this:

javac ImportTests.java

The result is having the compiled .class file in the same location with the .java source code file. That seems OK until we run it like this:

java ImportTests

Ups… Hitting a roadblock.

roadblock

The problem here is that, java cannot find the class because, for each path in the java class path, it is looking for it under the blog/mertersualp/imports folder. So, one effect of package declaration is that, the .class presents itself under the folder structure defined exactly as the package declaration. There must be a way to put the compiled .class file to its proper place. This can be done by using the -d parameter while compiling the source code. With that, we specify the folder where the packaging structure begins. In our example, the absolute path of the source code is

/Users/merter/Documents/javaSpace/ImportTests.java

The following compilation command will compile this file and put it under the proper place for the class. If the package folders are missing, compiler will create them. But the path provided to the -d parameter must exist beforehand.

javac -d /Users/merter/Documents/javaSpace /Users/merter/Documents/javaSpace/ImportTests.java

This will create the file structure under the /Users/merter/Documents/javaSpace folder. So, the final ImportTests.class file can be found in /Users/merter/Documents/javaSpace/blog/mertersualp/imports/

With all these in place, we can run the .class file in two different ways:

java -cp /Users/merter/Documents/javaSpace blog.mertersualp.imports.ImportTests
java -cp /Users/merter/Documents/javaSpace blog/mertersualp/imports/ImportTests

proper placement

We can compile simultaneously more than one class, which may or may not share the same package. Suppose that we have another class, ImportChildTests.java. It is not in the same package, but its package is under that. In Java terminology, this is a child package. The code is here.

package blog.mertersualp.imports.children;

public class ImportChildTests {
  public static final int CHILD_LIMIT = 5;

  public static void main(String[] args) {
    System.out.println("ImportChildTests main method is running.");
  }
  
  public int nonStaticMethod() {
    System.out.println("ImportChildTests nonStaticMethod is running.");
    return 1;
  }
}

This class is more or less the same with the first one. Assuming that both these source codes are in the same location, and we are also in that folder, we can compile them with the following command:

javac -d . Import*.java

The two paths, /Users/merter/Documents/javaSpace/blog/mertersualp/imports/ and /Users/merter/Documents/javaSpace/blog/mertersualp/imports/children/ are created, if they do not exist already, and the two .class files will be put under their corresponding locations. As we can see, the package declarations again dictate the final locations of the .class files.

Importing

Until here, we talked about compiling and finding the right class in the right place while running the programs. Here, we will try to understand what is needed and what happens when we access a class inside another package. Almost all classes Java developers use are contained within many different packages. There is only one exception to this, which is the java.lang package. It is so vital for Java that, it is literally impossible to do anything without it. Henceforth, it is imported implicitly for all Java classes. Other than those, every class accessed must be referred correctly. To do that, we must be sure of two things:

  • The referred class must exist under the class path, with its proper folder structure according to its package name
  • In the source code, that class must be explicitly imported

So we came to the point of importing classes. In Java, the first non-comment line of the source codes contains the package name. After that, the import expressions must be written. Either, we can make a single-type-import for that class/interface, or all classes/interfaces under a specific package. The “all” part is defined by an asterisk (). java.util. means all classes/interfaces of the java.util.package. There are two important points here. The first one is that, by this way, only classes/interfaces can be imported. The other one is, the child packages of java.util ARE NOT imported. They must be explicitly imported. In this case, if we want to use Semaphore class in java.util.concurrent package, we also need to import that class or all classes/interfaces inside java.util.concurrent. A List of Semaphores can be used as in below:

import java.util.List; //import java.util.* also fine
import java.util.concurrent.Semaphore; // java.util.concurrent.* also fine

public class ConcurrencyCollection {
  private List<Semaphore> listOfSemaphores;
}

The rule is: When a class/interface is referenced inside a Java code, its package name is prefixed and searched for in the class path. So, according to the above statements, when we refer to a List object, the compiler searches for java.util.List in the class path. This means that, we can also achieve the same result without using imports, but explicitly using fully-qualified names of the classes. The following code is perfectly valid.

public class ConcurrencyCollection {
  private java.util.List<java.util.concurrent.Semaphore> listOfSemaphores;
}

It is cumbersome to write the fully-qualified names of each class/interface, therefore import mechanism is used extensively. However, this representation is very important and can be a life saver in some situations. For example, let’s assume that we need to import all classes/interfaces in java.util and java.awt packages. We would like to have a List of Semaphores again.

import java.util.*;
import java.util.concurrent.*;
import java.awt.*;

public class ConcurrencyCollection {
  private List<Semaphore> listOfSemaphores;
}

ambiguity

Since List class/interface happens to be in both java.util and java.awt packages, compiler cannot decide which one we are trying to use. In this very specific case, we must use the fully-qualified name of the List interface. The small modification below makes everything ok again.

import java.util.*;
import java.util.concurrent.*;
import java.awt.*;

public class ConcurrencyCollection {
  private java.util.List<Semaphore> listOfSemaphores;
}

If the only class/interface we are interested in java.util package is the List, then we have another option.

import java.util.List;
import java.util.concurrent.*;
import java.awt.*;

public class ConcurrencyCollection {
  private List<Semaphore> listOfSemaphores;
}

Wow, it just compiled smoothly! The magic here is that, single-type-imports override wildcards. Throughout the source code file, the List will be assumed to be java.util.List. Therefore, single-type-imports for classes/interfaces can be a better choice when dealing with many imports. Of course, when the classes/interfaces having the same name are imported in a single-type fashion, the compiler refuses to proceed successfully, because of a collision. 

import java.util.List;
import java.util.concurrent.*;
import java.awt.List;

public class ConcurrencyCollection {
  private List<Semaphore> listOfSemaphores;
}
collision

Static Import

I said that the import mechanism only works for classes and interfaces but, frankly, it is not totally true. Starting with Java 5, a new way to import public static fields and methods was introduced. That is static import. The aim of it is to eliminate Constant Interface Anti-pattern. Software developers devised this anti-pattern to share the static fields in their many classes without a qualification. There are many frequently used constants, such as Math.PI, Integer.MAX_VALUE, Long.MIN_VALUE, e.g. To bypass their corresponding class names, an interface can be created and these values can be put into it as the only API. Abusing the interface mechanism can yield to significant problems. Instead, we can create single utility classes, put those public static fields as final. Then, use them by statically importing, which practically achieves the same result with lesser side-effects. Although it is a valid option, usage of it is generally discouraged.