Java Performance: what developers must know

I have observed that developers (myself included) tend to focus more on the make it work and make it right stages of building software, and less on the make it fast part. The consequence? Sometimes our applications behave very badly under significant or even moderate load, and we generally realize that too late… ūüĒ•

Recently, I’ve been involved in solving performance issues at many levels, mostly on Java applications. In this presentation, I list some tools and techniques that were very helpful to me in order to find, fix and prevent from performance issues.

Advertisements
Posted in Uncategorized | Tagged , | 2 Comments

Java: Inner Classes

Since Java 1.1, when inner classes were first introduced, they have started a lot of discussion. Some people like them and find them useful. Others hate them. Point of views apart, the fact is that inner classes can be helpful in many situations.

Basically, inner classes give us the ability to define one class within another.

In general, we divide classes in four groups:

  • Inner classes
  • Anonymous inner classes
  • Method-local inner classes
  • Static inner classes

Examples showed on this post were built using a JDK 6.

Inner Classes

Inner classes are generally used when some pieces of the code of different classes are intimately tied.

Let’s use a chat application as an example. When someone is chatting, the application needs to handle a couple of things in the background, like, listening and writing into sockets, reading messages from text fields, sending messages when the “Send” button is pressed, etc. The handlers (in this case the Java components that help us to send and receive messages) are strongly tied to some components of the chat’s client. These handlers need to access members of a specific object, like buttons, text fields, etc. Thus, we tend to implement these handlers as inner classes in such a way they share a special relationship with their outer class instance. As the inner class is part of the outer class, it can access the private members of its outer class.

Following a simple example of an inner class.

public class OuterClass {
    private int index = 0;

    class InnerClass {
        public void printIndex() {
            // Because the inner class is a member of the
            // outer class, it can access its private members
            System.out.println("Index: " + index);
        }
    }
}

Compiling the above example will produce two class files:

OuterClass.class
OuterClass$InnerClass.class

An inner class has its own class file. Nevertheless, it is not possible to execute the inner class file in the usual way by doing java¬†OuterClass$InnerClass.¬† That’s because a simple inner class cannot have static declarations, and then it is not possible to put a main method on it.

The only way to access inner classes members is through an instance of the outer class. This is only possible at runtime when there is an instance of the inner class tied to its outer class. In other words, an inner class instance cannot stand alone without an outer class instance.

Following an example of an outer class using an inner class.

public class MyOuterClass {
    private int index = 0;

    public void usingInnerClass() {
        // The only way to access MyInnerClass instance is
        // through MyOuterClass instance.
        MyInnerClass innerClass = new MyInnerClass();
        innerClass.printIndex();
    }

    class MyInnerClass {
        public void printIndex() {
            // Because the inner class is a member of the
            // outer class, it can access its private members.
            System.out.println("Index: " + index);
        }
    }
}

However, it is possible to call methods of inner classes directly from a static context. As every inner class instance is tied to its outer class instance, we need an outer class instance for this. Let’s see an example:

public class InnerClassAccessor {
    public static void main(String... args) {
        MyOuterClass.MyInnerClass myInnerClass = new MyOuterClass().new MyInnerClass();
        myInnerClass.printIndex(); // will print Index: 0
    }
}

Magic? No, it’s only the keyword new called from an object! Instantiating an inner class is the only case where we can call new on an object instance, rather than invoking new to construct an instance. This is a special way to instantiate inner class from outside the class it lives in.

Finally, since the keyword this always refers to the current object instance, the same keyword used within an inner class refers to the instance of the inner class itself. So, when an inner class needs to refer to a member of the outer class, it needs to use the NameOfTheOuterClass followed by .this.

public class SecondOuterClass {
    private String classAlias = "outer alias";

    class InnerClass {
        String classAlias = "inner alias";

        public void printAlias() {
            System.out.println("Outer: " + SecondOuterClass.this.classAlias);
            System.out.println("Inner: " + this.classAlias);
        }
    }

    public static void main(String... args) {
        InnerClass innerClass = new SecondOuterClass().new InnerClass();
        innerClass.printAlias();    // will print   Outer: outer alias
                                    //              Inner: inner alias
    }
}

Anonymous inner classes

Anonymous inner classes are called “anonymous” because they don’t have a class name. Anonymous inner classes can be used in many situations: inside a method, as a class member or even as a method argument.

Bellow an example of anonymous inner class defined inside a method.

abstract class Bird {
    abstract void fly();
}

public class AnonymousInnerClass {
    public static void main(String... args) {
        Bird bird = new Bird() {
            @Override
            void fly() {
                System.out.println("Flying...");
            }
        };  // Semicolon required!

        bird.fly(); // Will print Flying...
    }
}

It is important to note that when using anonymous inner classes as a class member or a local variable inside a method, the semicolon is required at the end of the class instantiation. If the semicolon is omitted the code does not compile.

Anonymous inner classes are available in two flavours. The first one is called anonymous subclass. Anonymous subclasses are created extending a class. The second flavour is called anonymous implementer and is created when implementing anonymously an interface.

Another point to be mentioned is that methods defined inside anonymous inner classes other those overridden from the super class or the interface cannot be called from the outside. Since Java is a strongly typed language, only methods defined by the type can be called. 

Method-local inner classes

Simple inner classes are defined inside a class, more specifically inside the curly braces of a class. Method-local inner classes are inner classes defined inside methods and can only be used within the method they are defined in. The only place from where we can create an instance of a method-local inner class is inside the method where the same inner class was defined.

public class MethodLocalInnerClass {
    private int x = 10;

    void printFromInner() {
        class InnerClass {
            public void printX() {
                System.out.println("x=" + x);
            }
        }

        InnerClass innerClass = new InnerClass(); // must come after the class
        innerClass.printX();
    }
}

Worth noting: method-local inner classes cannot access the local variables of the method the inner class was defined in (if you try the compiler will complain). The reason is that, as the local variables of the method live in the stack, they exist only during the method execution lifetime. So, if an instance of a method-local inner class is passed to another class and it is being used there, when the method ends, its local variables won’t exist anymore. We can only use method-local variables inside method-local inner classes if they were declared final.¬†Once it has been assigned, the value of the¬†final¬†variable cannot change. This allows the Java compiler to “capture” the value of the variable at runtime and store a copy as a field in the inner class.

class MethodLocalInnerClass2 {
    private int x = 10;

    public static void main(String... args) {
        MethodLocalInnerClass2 clazz = new MethodLocalInnerClass2();
        clazz.printFromInner(); // will print x=101
    }

    void printFromInner() {
        final int y = 1;
        class InnerClass {
            public void printX() {
                System.out.println("x=" + x + y);
            }
        }

        InnerClass innerClass = new InnerClass(); // must come after the class
        innerClass.printX();
    }
}

And only to remember, local variables rules are also applied to method-local inner classes and they cannot be declared public, private, static, protected, transient, etc. Only abstract and final are allowed.

This question on stackoverflow contains some good examples regarding the usage of method-local inner classes.

Static inner classes

Static inner classes or static nested classes are members of the outer class that can be accessed from a static context. In this case, static inner classes can be accessed like any other static member, without having an instance of the outer class.

Although, unlike other inner classes, static inner classes don’t have any kind of special relationship with the outer class, except the namespace. In other words, they cannot access non-static members of the outer class.

class HelperClass {
    static class InnerHelper {
        void print() {
            doPrint();
        }
    }

    static void doPrint() {
        System.out.println("Printing from HelperClass");
    }
}

public class StaticInnerClassExample {
    static class AnotherHelper {
        void print() {
            System.out.println("Printing from AnotherHelper");
        }
    }

    public static void main(String... args) {
        /* Note the way we create an instance of a static inner class
         is not the same as for inner classes */
        HelperClass.InnerHelper h1 = new HelperClass.InnerHelper();
        h1.print(); // will print: Printing from HelperClass
        AnotherHelper h2 = new AnotherHelper();
        h2.print(); // will print: Printing from AnotherHelper
    }
}

Note: A non-static nested class (or “inner class”) has full access to the members of the class within which it is nested. A static nested class does not have a reference to a nesting instance, so a static nested class cannot invoke non-static methods or access non-static fields of an instance of the class it is nested on.

Posted in Uncategorized | Tagged , | 1 Comment

Carreira e TI

No dia 17 de fevereiro de 2012, eu fui convidado pelo pessoal da ComputerTec de Araguari-MG para falar sobre tendências na área de Tecnologia da Informação (TI).

Junto com algumas pessoas da empresa, conversamos sobre a carreira do profissional de TI e as tendências do ramo naquele momento.

Como a ComputerTec atua na √°rea de venda de equipamentos e manuten√ß√Ķes, e eu na √°rea de engenharia de software, a conversa foi bem interessante, pois trabalhamos em espectros distintos do nosso ramo.

Foi uma conversa bem agrad√°vel e quero aqui agradecer pelo convite.

Publico abaixo os slides usados na apresentação.

Posted in Uncategorized | Tagged , , , | 2 Comments

Java: Generic Types

Code samples in this post were compiled with a JDK 6.

Before Java 5, it was not possible to instruct to a collection (like a List, a Map or a Set) to accept only objects of a specific type. At that moment, collections could hold anything that was not a primitive type (which are boxed when added to the collection). For that reason, applications before Java 5 were “less type safe” and more error prone when manipulating collections.

Here’s an example:


List list = new ArrayList();

// We can add whatever we want...
list.add("string");
list.add(1);
list.add(4.0);
list.add(new Object());

This approach can be a little bit dangerous, particularly when working with external APIs.

Suppose that in your code you call a method of an external class (third party code) that manipulates lists of Strings and gets a List as parameter. For any reason, you put an Integer inside a List object and you pass it to the method. Inside the method, a cast is required to get elements of the list and assign them to variables, like String value = (String) list.get(0). Since you can have limited or even no access to the foreign code, you can inadvertently get a RuntimeException when the method will try to cast the Integer element into a String O_o

Java 5 introduced Generics. With generics, we can guarantee which object type a collection can hold. If we declare a collection with a given type and we try to add to it an object of a different type, we get a compilation error. The type validation is performed by the compiler. Generics are not present inside the bytecode, so they are not used on runtime.

Using generics is simple! Just add a type inside angle brackets <> immediately following the collection type. This needs to be done in the variable declaration and in the constructor call. Finally, generics can also be used as type parameters and return types for methods.

import java.util.ArrayList;
import java.util.List;

public class GenericTypes {
    public static void main(String... args) {
        GenericTypes gt = new GenericTypes();

        // We define a list of Strings
        List<String> people = gt.getArrayList();
        people.add("Alice");
        people.add("Bob");

        gt.printList(people);
    }

    void printList(List<String> list) { // Now casts are not necessary
        for(String name : list) {
            System.out.println(name);
        }
    }

    List<String> getArrayList() {
        return new ArrayList<String>();
    }
}

Legacy code

As said before, generic types are not present during runtime. The type compliance check is made by the compiler. Once the code is compiled, collections post and pre-Java 5 are the same thing. The reason is simple: retro-compatibility. Sun did not want to break code written before Java 5, so the type verification does not exist in runtime. By doing this, legacy and post-Java 5 code can interoperate.

import java.util.ArrayList;
import java.util.List;

public class LegacyExample {
 public static void main(String... args) {
  List<String> list = new ArrayList<String>();
  list.add("1");
  list.add("2");

  LegacyExample le = new LegacyExample();
  le.addObject(list);
 }

 void addObject(/*Parameters here are non-type safe*/ List list) {
  list.add(1);
 }
}

The code above compiles and runs without errors. Even if the object added to list object inside the addObject method is different from the type accepted by the List, it will work. This happens because type-safe protection does NOT exist at runtime. Nevertheless, the compiler will identify that the code is not as safe as it could be and will issue warnings:

$ javac LegacyExample.java
Note: LegacyExample.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

As pointed out in the warning, it is possible to identify which method is to blame. To find that out, just recompile with -Xlint:unchecked option.

$ javac -Xlint:unchecked LegacyExample.java
LegacyExample.java:18: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
list.add(1);
        ^ 1 warning

At this point, you may have a question. If it is not possible to have type-safe protection at runtime like arrays, what are the advantages in using generics?

Generic types bring mainly two advantages:

  • Type-safe verification at compile time
  • No need for object casting when you get something out of a collection

Generics and Polymorphism

It is important to point out that there are a couple of differences between arrays and generic collections. Let’s see some examples:

import java.util.ArrayList;
import java.util.List;

class Professional{}
class Engineer extends Professional {}

public class ArraysXCollections {
 public static void main(String... args) {
  Professional[] professionals = new Engineer[5]; // This works fine
  List<Professional> professionalList = new ArrayList<? extends Professional>(); // But this does not compile
 }
}

Generic types do not support natural polymorphism. The reason is simple. Imagine that we have a method receiving List list as parameter. So, we could perfectly pass an ArrayList list to that method. Right. The problem is that, by doing this, we allow the code inside the method to add to the list any object that passes an IS-A test with Professional that is not an Engineer. In the end, there is no guarantee that the collection of engineers given to the method in the past still holds only engineers and this can be dangerous :S

However, it is possible to add Engineers into a collection of Professionals:

public class CollectionsExample {
    public static void main(String... args) {

        List<Professional> professionalList = new ArrayList<Professional>(); // No problem here

        professionalList.add(new Engineer());   // This is allowed

        addElements(professionalList);          // Everything is fine
    }

    static void addElements(List<Professional> list) {
        list.add(new Engineer());
    }
}

To solve the problem of manipulating sub and super types in generic collections, Java has a mechanism called “wildcards”, like . By using the type List as a method parameter, we can pass any list to that method since its generic type passes an IS-A test for Professional. The only restriction is, when using something like List (or even simply List), it is not possible to insert any object into the list (otherwise, a compiler error will occur):

import java.util.ArrayList;
import java.util.List;

public class Wildcard {

    public static void main(String... args) {
        List<Engineer> engineers = new
        ArrayList<Engineer>(); addElement(engineers);
    }

    static void addElement(List<? extends Professional> list) {
        list.add(new Engineer());   // This line does not compile
    }
}

In the example above, if we delete the instruction list.add(new Engineer()) the code compiles and runs fine.

On the other hand, it is possible to deal with the insert restriction imposed by the keyword extends used with the wildcard ?. By using the keyword super, it is possible to add elements into a collection received as parameter.

public class Wildcard2 {
    public static void main(String... args) {
        List<Professional> list = new ArrayList<Professional>();
        addElements(list);
    }

    static void addElements(List<? super Engineer> list) {
        list.add(new Engineer()); // this line compiles fine
    }
}

When the keyword super is used, Engineers and any super-type of Engineer – like Professional, and obviously Object – will be accepted. Maybe this will not shock you, since upcasts are natural in Java (like putting a String into an Object).

Summarizing, List and List are the same thing. Nevertheless, neither of them are the same as List, because the later will leave you add elements inside. Wildcards are used only for reference declarations like arguments, return types and variables. Wildcards cannot be used as generic type to create new typed collections.

Parameterised Types

It is possible to use generic types to create “template classes” that can safely manipulate objects of any type. In this case, generic types are used as instance variables giving a class the chance to manipulate objects generically:

class Test<T> {
    T t;

    public Test(T t) {
        this.t = t;
    }

    public T getT() {
        return t;
    }
}

public class GenericTypeExample {
    public static void main(String...  args) {
        Test<String> test = new Test<String>("Generics");
        System.out.print(test.getT());  // will print Generics
    }
}

In the example above, T is a placeholder used to designate a parameter type for the class. We could have used anything else, but T is a convention for class parameter types. The placeholder E, for example, designate “Element” and is used when the template is a collection (see List for example). The wildcard notation can be used in many ways to combine types and create templates.

class Converter<T, Y> {}
class Calculator<T extends Number> {}
public class GenericTypeExample2 {
    Converter<Integer, Long> converter = new Converter<Integer, Long>();
    Calculator<Integer> calculator = new Calculator<Integer>();
}

However, it is also possible to use parameterised types to ensure type safety only in methods. This is used when only the method needs to be aware of the generic type, not the whole class.Let’s suppose we need a generic method to create a parameterised Map for cache purposes.

import
java.util.HashMap;import
java.util.Map;class Cache {
    static <K, V>  Map<K,V> getCache() {
        return new HashMap<K, V>();
    }
}

public class CacheTest {
    public static void main(String...  args) {
        Map<Integer, String> cache = Cache.<Integer,String>getCache();
        cache.put(1, "test1");
        cache.put(2, "test2");
    }
}

In this example, K is replaced by Integer and V by String. In generic methods, it is necessary to declare the parameterised types before using them: static Map getCache(). We must do this in order to define what K and V are before using them as parameters or return types. If the type is defined in the class, it is not necessary to re-define it in the method signature. Worth noting it is also possible to use boundaries in generic methods: static <K, V extends Object> Map getCache().

Update: From Java 7 on, the diamond operator was introduced in order to spare developers of repeating the generic type twice, like:

// Instead of doing:
List<Professional> list = new ArrayList<Professional>();

// You can now do:
List<Professional> list = new ArrayList<>();
Posted in Uncategorized | Tagged , | Leave a comment

Java: Operators

As in mathematics, operators in Java are used to produce new values from operands. Choosing the right operator at the right time is important in order to write clear code in a fast way.

Code samples in this post were compiled with a JDK 6.

Assignment Operators

The most common assignment operator in Java is the = operator. This operator simply assign values to variables. Nevertheless, the = operator can be composed with other operators like +, -, *, /, >>, <<, & and | forming the compound operators: +=, -=, *=, /=, >>=, <<=, &= and |=.

        int i = 0;
        int j = 0;

        i += 2;         // Which is the same that i = i + 2;
        j *= 10 + 4;    // Which is the same that j = j * (10 + 4)

Relational Operators

Relational operators are often used on if tests and result in a boolean value (true or false). Java has six relational operators which are: >, >=, <, <=, ==, and !=. All of them can perform comparisons on integers, floating-points or characters. Only the last two (== and !=) are used to perform comaprisons on boolean values, or object reference variables.

        char sex = 'f';

        if(sex
        Relational r1 = new Relational();
        Relational r2 = new Relational();

        if(r1 == r2) {} // false

        r1 = r2;        // now they hold the same reference

        if(r1 == r2) {} // true

instanceof Operator

The instanceof operator verifies if an object is of a particular type. To evaluate the type of an object (on the left), the operator uses a IS-A test for a class or interface (on the right). The IS-A test returns true if the object inherits from the class or implements the interface used in the test. Otherwise, the result is false.

class A {}
class B extends A {}

public class InstanceOf {
    public static void main(String... args) {
        A a = new B();
        B b;

        if(a instanceof B) {    // the IS-A test passes
            b = (B)a;   // we can then downcast
        }
    }
}

Arithmetic Operators

Beyond the basic arithmetic operators +, -, *, and /, there are three other operators also widely used which are:

  • the Remainder operator (%);
  • the String Concatenation operator (+);
  • the Increment and Decrement operators (++¬†and¬†--,¬†respectively).

The remainder operator % returns the remainder of a division operation.

        int x = 10;
        int y = 4;

        int rem = x % y;    // which will be 2

Observation: in Java expressions are evaluated from left to right. The operators *, /, and % have higher priority then + and - operators. Parentheses can be used to change the evaluation order.

The operator + can act as addition operator or string concatenation operator, which depends on the operands. If there is a string among the operands, the + becomes a string concatenation operator. If the operands are numbers, the + will perform the addition.

        int i = 5;
        int j = 5;

        System.out.println("String" + i);   // will print String5

        System.out.println("String" + (i + j)); // will print String10
                                                // because the parentheses

Finally, the increment and decrement operators will increment or decrement variables by one. The operator can prefix or postfix the operand. When the prefix approach is used, the operator is placed before the variable, and the operation is performed before the variable is used. When the postfix approach is employed, the operator is placed after the variable, and the increment or decrement operation takes place after the variable is used.

public class IncrementDecrement {
    public static void main(String... args) {

        int i = 0;

        if(++i == 1) {
            System.out.println("++i is performed before the test");
        }

        System.out.println("i = " + i--); // output : i = 1

    }
}

Conditional Operators

The ternary conditional operator will decide which value to assign or return after evaluating a boolean expression. Here is the structure of the conditional operator:

   (boolean expression) ? value if true : value if false

The first value is assigned or returned if the result of the expression is true. Otherwise, the second value is used. The parentheses are optionals and it is possible to nest conditional operators.


public class ConditionalTest {
    public static void main(String... args) {
        int i = 4;
        int j = 5;

        String result = ++i == 4 ? "i=4" :
                (i + j++ > 10) ? "i+j>10" : "i+j    }
}

Logical Operators

Logical operators in Java basically evaluate an expression and return a boolean value.

Short-Circuit Logical Operators

Short-circuit operators evaluate boolean expressions and return boolean values. Short-circuit operators are represented as follow:

  • || short-circuit OR
  • && short-circuit AND

A short-circuit AND (&&) will evaluate the left side of an expression first. If the result is false, the operator will not waste time evaluating the right side and will return false. The right side will be evaluated only if the result of the left side is true. If the result of both sides is true, the hole expression is evaluated as true. If one of them results false, the expression is evaluated as false.

As the short-circuit AND, the short-circuit OR (||) will start evaluating the left side of the expression. Nevertheless, if the result is true the right side will not be analysed and the result of the whole expression will be true. The right side will be evaluated only if the result of the expression on left side  is false. So, if there is one true, the global result is true. If both sides are false, the final result is false.

public class ShortCircuitLogicalOperator {
    public static void main(String... args) {
        if(check(9) && check(11)) {
            System.out.println("First IF");
        }

        if(false || check(13)) {
            System.out.println("Second IF");
        }
    }

    private static boolean check(int value) {
        if(value % 2 < 2) {
            return true;
        }

        return false;
    }
}

The output of the code above is:

First IF
Second IF

Not Short-Circuit Logical Operators

Not short-circuit operators are represented as follows:

  • | non-short-circuit OR
  • & non-short-circuit AND

As not short-circuit operators will evaluate logical expressions like the operators && and ||. On the other hand, not short-circuit operators will evaluated ALWAYS both sides of the expression. Non-short-circuit OR (|) will return false if both sides of the logical expression are false. It returns true if one side is true. Non-short-circuit AND (&) returns true only if both sides are evaluated as true. Otherwise, it returns false.

public class NotShortCircuitLogicalOperator {
    public static void main(String... args) {
        int i = 0;

        if((i++ < 1 & ++i > 1) | i == 2) {
            System.out.println("Little puzzle");
        }
    }
}

Boolean Invert Logical Operator

The unary boolean invert (!) operator evaluates only boolean expression and returns its opposite value. So, if the result is true, it gets false and vice-versa.

Exclusive-OR (XOR) Logical Operator

The exclusive-OR (^) operator also used with boolean expressions and it evaluates BOTH sides of an expression. For an exclusive-OR (^) expression be true, EXACTLY one operand must be true.

public class ExclusiveOR {

    public static void main(String... args) {
        byte size1 = -127;
        byte size2 = 127;

        if(checkSize(size1) ^ checkSize(size2)) {
            System.out.println("There is a size that passes the" +
                    " check AND a size that does not match. ");
        }
    }

    private static boolean checkSize(byte i) {
        if(i < 127) {
            return true;
        }

        return false;
    }
}

Bitwise Operators

Bitwise operators are operators that evaluate the bit value of each operand. They are used in expressions with integer values. If the operand is smaller than int, the primitive value will be converted to an int.

Following a list with the bitwise operators in Java.

  • ~ unary bitwise complement
  • & bitwise AND
  • | bitwise OR
  • ^ bitwise XOR
  • Shift operators: <<, >>, and >>>

The unary bitwise complement simply invert the bit value. The bitwise operators AND, OR and XOR evaluate bits using simple logic. The shift operator << shifts bits of to left putting zeros on the right side (low order position). The shift operator >> shifts bits to the right side saving the number sign. In other words, a negative number remains negative after the operation. Finally, the shift operator >>> move bits to right without saving the number sign. In this case, zeros are inserted as most significant bits (on the left). All the operators can be also used with the assignment (=) operator.

Bitwise operators are generally used to pack a lot of information into a single variable, like masks, flags, etc.

public class BitwiseOperators {
    public static void main(String... args) {
        short i = 127;
        long j = 0;
        byte k = 85; // binary: 0101 0101
        int l = 99; // binary: 0000 0000 0000 0000 0000 0000 0110 0011
        int m = -99; // binary: 1111 1111 1111 1111 1111 1111 1001 1101

        System.out.println("~i  = " + ~i);
        System.out.println("i&j = " + (i&j));
        System.out.println("i|j = " + (i|j));
        System.out.println("i^j = " + (i^k));

        j |= i;

        System.out.println("j (after j |= i) = " + j);

        System.out.println("m>>4 = " + (m>>4)); // binary: 1111 1111 1111 1111 1111 1111 1111 1001
        System.out.println("m>>>12 = " + (m>>>12)); // binary: 0000 0000 0000 1111 1111 1111 1111 1111
    }
}

The output of the code above will be:

~i  = -128
i&j = 0
i|j = 127
i^j = 42
j (after j |= i) = 127
m>>4 = -7
m>>>2 = 1048575

Observation: Java uses¬†two’s-complement mechanism to sign integral types. More on this here.

Posted in Uncategorized | Tagged , | Leave a comment

Java: Garbage Collector

Code samples in this post were compiled with a JDK 6.

Garbage collection is one of the big advantages of Java. Many languages like C and C++ do not offer an automatic mechanism to perform memory management. Manually releasing every object which is not being used anymore could become a fastidious and a really difficult task.

When memory is not correctly managed, objects can stay allocated indefinitely, making applications to consume more memory than what they actually need. This can lead to performance and memory management issues, and eventually make the application crash. Such problem is known as memory leak.

The garbage collector (GC) removes from the heap (memory area where Java objects live) objects that were discarded and won’t be used anymore by a Java program.

It is the JVM that decides when to run the garbage collector. Throughout a Java program, it’s possible to ask the JVM to run the garbage collector using System.gc(). Nevertheless, there are no guarantees that the request will be attended. So, it’s not a good practice to design an application relying on the execution of the garbage collection.

In Java, objects are allocated on the heap space. The mission of the garbage collector is to make sure that the heap has as much free space as possible. It ensures that the available memory will be managed efficiently, but it cannot guarantee that there will be always enough space.

It is important to identify when an object is eligible for garbage collection. In Java, an object is eligible for deletion when it cannot be accessed by any live thread. In other words, if all the references to an object cannot be reached by a live thread the object is marked for collection. Obviously, if there are no reachable references to an object, we don’t care about that object anymore.

There are basically three ways to mark an object for garbage collection:

  • Nullifying a reference
  • Reassigning another value to the reference
  • Isolating a reference
public class GC {
    GC gc;

    public static void main(String... args) {
        // Nulling the object
        StringBuilder nulling = new StringBuilder("nulling");
        nulling = null;  // nulling is now eligible for garbage collection

        // Reassigning a new value to the object
        StringBuilder first = new StringBuilder("first string");
        StringBuilder second = new StringBuilder("second string");

        first = second; // now second is marked to be collected

        // Isolated island
        GC gc1 = new GC();
        GC gc2 = new GC();
        GC gc3 = new GC();

        // creating a circular reference
        gc1.gc = gc2;
        gc2.gc = gc3;
        gc3.gc = gc1;

        // now there is an island that cannot be reached
        gc1 = gc2 = gc3 = null;
    }
}

Finally, it is also possible to execute some operations just before an object is deleted by the garbage collector. In order to do that we need to override the method finalize() inherited from class Object. But be careful, as we have no guarantees about when the GC will run, the code inside the method finalize() can wait a very long time to be executed. For that reason, it is recommended to not use the finalize() method to release resources allocated by an object. Use an explicit method call for that instead.

Posted in Uncategorized | Tagged , | Leave a comment

Java: Passing Variables into Methods

Java use pass-by-value semantics, instead of pass-by-reference, when passing variables to methods.

During a method call for example, Java will copy values given by the caller and will pass them to the callee method. If the variable has a primitive type, the value of the variable is copied and passed through. If the method changes the value received as argument, the variable’s value on the caller side will remain unchanged.

However, when the argument is an object, since Java copies the variable’s value and, since in this case the value is a reference (the address of the object on the heap), operations performed on that object will take effect on the caller (assuming the object has mutable state).

Code samples in this post were compiled with a JDK 6.

Wrappers

Wrappers are Java objects that encapsulate primitive types. Wrappers have two main purposes:

  • provide utility functions for primitive types
  • allow primitive types to be used where only objects are accepted

Every primitive type has a wrapper class associated.

Data Type Wrapper Class
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
char java.lang.Character
boolean java.lang.Boolean

Since Java 5, we can use a feature called autoboxing. Autoboxing allows us to perform conversions between primitive types and their wrappers automatically. With autoboxing it is possible to assign wrappers to primitive types and vice-versa without the necessity of calling wrapper methods to unwrap and re-wrap. These operations are usually called boxing and unboxing.

public class Wrappers {

    public static void main(String... args) {

        // Before Java 5
        Integer i = new Integer(5); // create
        int x = i.intValue();       // unwrap
        x += 10;                    // use
        i = new Integer(x);         // re-wrap

        // From Java 5 onwards
        Integer j = new Integer(5); // create
        j += 10;                    // use
    }
}

Observation: two autoboxed instances of types Boolean, Byte, Character from \u000 to \u007f (7f is 127 in decimal), Short and Integer (from -128 to 127); always pass a == test when their primitive values are the same. More about this can be found here.

Quiz: what is the output of the code below?

public class Quiz {
    public static void main(String... args) {
        Integer i1 = 1000;
        Integer i2 = 1000;

        if(i1 != i2) {
            System.out.print("1 ");
        }

        if(i1.equals(i2)) {
            System.out.print("2 ");
        }

        Integer i3 = 10;
        Integer i4 = 10;

        if(i3 == i4) {
            System.out.print("3 ");
        }

        if(i3.equals(i4)) {
            System.out.print("4");
        }
    }
}

Overloading

Overloading methods in Java can be a little bit difficult when many methods are eligible to match to a certain call. When this kind of situation happens, the Java compiler will use the following order of factors to determine which method will be invoked when an overloading happens:

  • Widening
  • Autoboxing
  • Var-args

When there is a dispute, widening is the winner over autoboxing and var-args. When there is a dispute between autoboxing and var-args, autoboxing wins.

public class Overloading {

    static void doSomething(long x) {
        System.out.println("long");
    }

    static void doSomething(Integer i) {
        System.out.println("Integer");
    }

    static void doSomething(Integer i, Integer j) {
        System.out.println("Integer Integer");
    }

    static void doSomething(int... ints) {
        System.out.println("ints...");
    }

    public static void main(String[] args) {
        int i = 10;
        int j = 20;

        doSomething(i);
        doSomething(i, j);
    }
}

In the example above, we first call the method doSomething passing an int as argument. As we have a widening and an autoboxing as options, widening wins and the argument is casted from int to long. In the second call, the compiler needs to decide between autoboxing and var-args. Since the first one has higher priority, autoboxing will be used. Executing the code above gives:

long
Integer Integer

Widening reference variables is also possible in Java. In this case, widening depends on inheritance and the IS-A test is used to perform the operation. Check the code below.

class Vehicle {}

class Car extends Vehicle {}

public class OverloadingReferences {

    static void doSomething(Vehicle vehicle) {}

    public static void main(String[] args) {
        Car car = new Car();
        doSomething(car);
    }
}

Observation: type castings using references are called upcast when the object is casted to one of the classes or interfaces it inherits from or implements, respectively. When the cast is made the other way round (towards a more specific object), it is called downcast.

Posted in Uncategorized | Tagged , , , | Leave a comment