Sep 22

I’ve been reading this post, which eventually led me to this JDK7 proposal. In the blog post itself, a lot of the comments were about whether the hash sign (#) or a more IntelliJ style @NotNull annotation should be used. One even suggested allowing for annotations defined in a certain package (say, java.lang.annotations) to be used with the @ sign in certain cases (such as parameter or method definition), making them “virtual keywords”. I’m not sure how this works for everything, but it’s an interesting idea.

In any case, Stephen’s reluctance from using @NotNull is seen both in his own comments:

Annotations are, according to the Sun guys, not to be used for language features. I agree.

And his proposition:

Alternate proposals suggest adding an @NotNull attribute to fields and parameters. Whilst this tackles the same problem area, it suffers from being verbose and intrusive. It is also the wrong device (an annotation) for fixing what is a language level missing piece (full handling and control of nulls). Finally, the annotation does not tackle the code clarity issues addressed in section II of this proposal.

I don’t tend to agree. First, it’s clear that the “Sun guys” are not so sure about this themselves, see JSR-305 tackling a very similar problem using annotations. Second, I’m less afraid of the verbosity of the annotation, especially if we’ll take JSR-305′s @DefaultNotNull or @DefaultNullable into account. Which is something that Stephen doesn’t address at all: What if I prefer to have non-null parameters and variables as the default? Unfortunately, this can’t be made the default – existing codebase will break if this was made the default. However, if we consider existing codebase as having the @DefaultNullable annotation, new classes could be written with a @DefaultNotNull annotation and there you go!

On the other hand, the @NotNull and @Nullable alternative doesn’t really deal with old codebase, since it doesn’t have a way to convert between a @Nullable (which might be the default for old codebase) and @NotNull (which is what I actually expect the code to return, in cases such as toString).

For a more concrete example, let’s compare the two options in a probable code written with the new null-safe feature:


class Person {
  private #List<#Person> children = ...;

  public #String getNameOfChildAtIndex(int childIndex) {
    // check for validity
    if (childIndex >= children.size()) ... ;
    // list is old Java
    #Person child = (#) children.get(childIndex);
    // toString is old Java, too.
    return (#) child.toString();
  }
}

On the other hand:



@DefaultNotNull
class Person {
  List<Person> children = ...;
    // both are automatically set to @NotNull
  String getNameOfChildAtIndex(int childIndex) {
    // check for validity
    if (childIndex >= children.size()) ... ;
    Person child = children.get(childIndex);
    // old code-base is not checked,
    // and might cause an error.
    return child.toString();
  }
}

There are other differences that make it harder to decide which is better. It is my opinion that the annotations’ solution is the better one, and we should be seeing more annotations adding Java features as time goes by, such as the @Override and @Deprecated annotations for methods.

Share
Sep 14

A class I find missing in the new java.util.concurrent package is PriorityBlockingDeque. Just like PriorityBlockingQueue, this class should be sorting its elements either by their natural order or by a supplied Comparator.

I fail to understand the reason for having this class obviously missing from the package, and because I need it very much, I decided to create a blocking wrapper around NavigableSet using locks and conditions. This uses NavigableSet’s already existing methods of pollFirst, pollLast, first and last to fulfil the Deque interface.

Update: After some comments appeared I’ve realised that by using NavigableSet I do not allow for duplicate values on the Deque. Therefore, I’ve changed the implementation to use LinkedList internally, using Collections.sort calls to keep the list sorted. Unfortunately, this brings the basic add operation to O(n log(n)), instead of the O(log(n)) it used to be.

The code is fully available here, as part of the collections project, and some unit tests are available here.

I will later post how I used it, but let me know if you used it and if it was of any help (or filled with bugs..)

Share
Aug 03

You know how you’re debugging, and you reach a method call that looks like methodCall(anotherMethod()) and you want to step over the call to anotherMethod but step into the call to methodCall? That’s where column-level debugger information could come handy.

And there are other cases as well:
Continue reading »

Share