Tuesday, January 4, 2011

Integer.MIN_VALUE is its own negative

Integer.MIN_VALUE == -(Integer.MIN_VALUE)

This is a very simple fact.

This happens on every language that uses two's complement to represent the numbers.
This issue is reflected in that the representation of the numbers is asymmetric (more negative values than positive values) and the zero has only one representation (which is also the negation of itself). Let's take for example 8 bits numbers (Java Integers are 32 bits but it's the same issue)

Zero in 8 bits:

00000000

two's complement of zero:

11111111 + 1 = 1(discarded)00000000


minimum negative number represented with 8 bits (Remember the first bit represents the sign)

10000000

two's complement of that number:

011111111 + 1 = 10000000
.......................
Quick Java Facts
Top Java books...

Wednesday, December 29, 2010

Raw references to Generic types erases Generic information

When you use a raw (without type parameter) reference to a generic type all generic information for that instance is lost. When I say all information is lost, I mean all instance member’s (fields, methods) get un-generic semantic (The compiler treats them as if no generic information exists at all, it somehow erases that information) even the generic information not related to the generic type we are using. See the following example that can be surprising, as it doesn’t even use the generic type parameter (T):



import java.util.ArrayList;
import java.util.List;
public class Generic<T>{
    public List<String> getStringList() {
        List<String> list = new ArrayList<String>();
        list.add("hola");
        list.add("ciao");
        return list;
    }
    public static void main(String[]args){
        Generic gen=new Generic<Object>();
        for(String string:gen.getStringList()){
            System.out.println(string);
        }
    }
}






The code doesn’t even compile!!. By using the raw reference in the line

Generic gen=new Generic<Object>;

the compiler is somehow erasing the generic information from the getStringList method, meaning that now the expected return type of the getStringList is simply List. So, you get the compiler error:

Type mismatch: cannot convert from element type Object to String in the for loop.
.......................
Quick Java Facts
Top Java books...

Monday, December 27, 2010

Override checks on run time, Overload on compile time

This is something that most people knows but sometimes forget.

Overriding is resolved against the runtime type of the object and overloading is resolved against the compile time type of the object.

To understand see the following code and what it prints:



public class Main {
    public static void main(String[] args) {
        Base a = new Derived();
        a.toOverride();
        a.overloaded(a);
    }
}
class Base{
    public void toOverride(){
        System.out.println("Override me");
    }
    public void overloaded(Base base){
        System.out.println("print  BASE");
    }
    public void overloaded(Derived derived){
        System.out.println("print  DERIVED");
    }
}
class Derived extends Base{
    @Override
    public void toOverride(){
        System.out.println("Overrided!!");
    }
}




The program prints

Overrided!!
print BASE


We can see that the variable "a" is of type Derived at runtime, but is declared with a reference to the type Base. When we invoke the toOverride method, the method in the Derived class is invoked. However when we invoke the overloaded method the method that gets called is the one that receives the Base parameter instead of the one that receives the Derived parameter.
.......................
Quick Java Facts
Top Java books...