List or List ?

Java 1.5 introduced some new concepts at the Java language level. One of them is Generics, which you can make use mainly when creating type safe collections. This new concept facilitates the programmers’ life: being type safe, errors when working with collections can be caught at compile time (if you have a List<String>in hand, only Strings can be added to this list, neither Integers, Cats or Dogs ) and the programmer doesn’t have to cast when taking out an object of a collection. I was thus wondering whether there is any difference between List<?> and List<Object>. Let’s take a look at the following lines of Java code:

   1:import java.util.ArrayList;
   2:import java.util.List;
   3:
   4:public class Music
   5:{
   6:    abstract class Instrument
   7:    {
   8:    }
   9:
  10:    class Guitar
  11:            extends Instrument
  12:    {
  13:    }
  14:
  15:    class Flute
  16:            extends Instrument
  17:    {
  18:    }
  19:
  20:    class Drums
  21:            extends Instrument
  22:    {
  23:    }
  24:
  25:    public static void main(String [ ] args)
  26:    {
  27:        List<Instrument> instruments =
  28:            new ArrayList<Instrument>();
  29:        List<Guitar> guitars = new ArrayList<Guitar>();
  30:        List<Flute> flutes = new ArrayList<Flute>();
  31:        List<Drums> drums = new ArrayList<Drums>();
  32:        List<Integer> integers = new ArrayList<Integer>();
  33:        List<Object> objects = new ArrayList<Object>();
  34:        check(instruments);
  35:        check(guitars);
  36:        check(flutes);
  37:        check(drums);
  38:        check(integers);
  39:        validate(objects);
  40:        validate(drums);
  41:    }
  42:
  43:    private static void check(List<?> instruments)
  44:    {
  45:    }
  46:
  47:    private static void validate
  48:        (List<Object> instruments)
  49:    {
  50:    }
  51:}

If you try to execute the lines of code, you´ll note:

  • List<?>, which is the wildcard <?> bounded type, also know as List<capture-of ?>, simply means “any type.” That is, it could be a List of <Guitar>, <Flute>,<Drums>, whatever. It also means that you cannot ADD anything to the list referred to as List<?>.
  • List<Object> only accepts Object as an argument. Not Guitars, Drums, Flutes or Integers. If you have a method which the argument specifies List<Object>, this method can only take a List<Object>. The compiler allows you to add to the List<Object>, since you pass an Object as an argument.

So, there are differences between List<?> and List<Object>. The above code doesn´t compile, because an List<Drums> is being passed to a method which has a List<Object> as argument. But if you modify the method to this one:

   1:private static void validate
   2:        (List<? extends Object> instruments)
   3:{
   4:}

The code now compiles!! So, we saw the behavior of List<?> and List<? extends Object> is the same! They both means “I can refer to any type of object”. But neither List<?> nor List<?> nor List<? extends Object> are the same as List<Object>. When you see code using the wildcard notation (?), you can think: “this code refer to many options”. If you try to add something to a List<?>, the compiler won’t let you, because whether it were possible, it would be an unsafe operation, as you could pass a List<Guitar> to a method which receives a List<?> and add, say, a String to the list, as List<?> accepts “any type”. So now you may think: “Ok, Generics is a good feature, I can now create type safe collections and work with them in a safer way at compile time, that’s very good”. But everything isn’t the way we’d want it to be. If you try to mix Java generics code and legacy code,

   1:private static void add(List instruments)
   2:{
   3:    instruments.add("45");
   4:}

and

   1:add(instruments);
   2:add(guitars);
   3:add(flutes);
   4:add(drums);
   5:add(integers);
   6:add(objects);

It compiles!! But let’s deal with it in another post.

Open sourcing Java: good or bad?

Sun announced it will start open sourcing Java by the end of this year, according to eweek. Sun plans to open-source firts the Java C (Java Compiler) and the HotSpot virtual machine, with the bulk of the rest of the code likely to follow in early 2007, including JavaME. Sun hasn’t decided which licence to choose yet, maybe GNU GPL (General PublicLicense) or CDDL (Common Development and Distribution License). What are the benefits of open sourcing Java? What do you think about the compatibility, if we have a lot of distributions of the technology? Nowadays we have this kind of thing with Linux distros, some are incompatible with the others. What’s your opinion about that?

Interfaces and Abstract classes

My friend bruno started a thread about interfaces and abstract classes and I wanna continue here. I totally agree with his points and I’m adding other ones here. About interfaces:

  1. define a communication “protocol” between classes.
  2. It is, a class which has an interface as a colaborator knows which operations it can send messages for this interface;

  3. isolate the clients from the implementation.
  4. So, you are free to change the internal structure of your implementation and the clients don’t have to concern with this. So, we are applying the hiding mechanism here, known as encapsulation;

  5. clients don’t have to concern with implementation details, because they only work with the interface. The real type doesn’t care for the client;
  6. define the form for a class. More precisely, is what the classes look like while the implementation says how the classes work.

About abstract classes:

  1. describe an incomplete abstraction definition, as interfaces do;
  2. define a common interface for all the subtypes;
  3. establish a basic form, so it’s easy to say what’s in common between the subtypes;
  4. express only a interface, not a particular implementation

Interfaces and abstract classes are ways of managing the internal coupling of your code. You create them when you want to manipulate classes through this common interface. If you only want to factor behavior, interfaces are a good choice, but if you want to factor structure too, choose abstract classes.

Thread Groups

Some months ago I was wondering what was the benefit of using thread groups, which is a container of threads in Java. Reading Bruce Eckel’s Thinking in Java, I discovered this quote from Joshua Block, the one who improved the Collections framework in JDK 1.2:

“Thread groups are best viewed as an unsuccessful experiment, and you may simply ignore their existence.”

I haven’t been told about any Sun’s official statement about this topic before reading the book. So, why do they let us spend our effort trying to figure out the value of thread groups? 🙂

About version control

What do java programmers version control? is a good question to ask ourselves in the corporate world of software development. I think we should version control all the stuff regarding to the project knowledge, such as documents, wireframes, prototypes, notes, requeriments and obvious, source code :-). If you have a wiki available, documents about the project can be put and edited there. I think the build process has to take care of creation and manipulation of other dependent libraries, they should not be versioned. At my company we use Ivy, a java based dependency manager for this purpose. I haven’t been told about this tool before but I found it quite interesting to work with dependencies. You can even specify which version of a specific jar you need, Ivy finds the correct version and applies it as a dependency to your project. It seems to be very useful to manage the dependencies of software projects. And in your company, what’s your team allowed to version control?

Guidelines about threads

From Bruce Eckel’s Thinking in Java book, about threads:

  1. If you need to synchronize one method in a class, synchronize all of them. It’s often difficult to tell for sure if a method will be negativelyaffected if you leave synchronization out.
  2. Be extremely careful when removing synchronization from methods. The typical reason to do this is for performance, but in JDK 1.3 and 1.4 the overhead of synchronized has been greatly reduced. In addition, you should only do this after using a profiler to determine that synchronized is indeed the bottleneck.