<< Previous | Home

Pop quizz Java: final vs. NPE, 0:1

Hah, that was a nice one! Given:

public class Foo extends Bar {
  final Object o;

  public Foo(Object o) {
    super(o);
    assert o != null;
    this.o = o;
  }

  @Override
  public void m() {
    assert o != null; /* Da bomb */
  }
}

Your task is to trigger the assertion in m(), while passing the one in the constructor. Hint: there's obviously not that much going on, so you might want to direct your attention to Bar

Tags : ,

The Futures of Java

Subtyping considered useful

So here I was playing with the type checker for our industrial-strength toy language ABS. This works, of course:

  interface A;
  interface B extends A;
  interface I {
     A doA();
     B doB();
  }

  Unit doIt() {
     I i = … ;
     /* All green, covariant return type: */
     A a = i.doB();
  }

A similar thing works of course also in Java. But, now back to the Futures! In ABS, we have futures, and of course it should be straight forward to turn the synchronous call into an asynchronous one:

   /* Works: */
  Fut<B> b = i!doB();
  A a = b.get; /* covariance for method "calls" (get is a special built-in) */

  /* Didn't - no covariance for parametric data types! */
  Fut<A> b = i!doB();

So I can do A a = i.doB() but not Fut<A> fa = i!doB(); A a = fa.get -- disappointing and not orthogonal at all!

While subtyping of parametric datatypes (in the functional subset of ABS!) can be easily told to make use of subtyping, it doesn't work that way in OO languages: the required subtyping rule would allow you to write values of the wrong type -- here's Jon Skeet explaining it why a list of animals is not the same as a list of cats or a list of dogs, and the hilarity that ensues when you mix them up.

As usual, functional programming saves the day.

Full Java code illustrating the problem for your delectation:

import java.util.concurrent.*;

interface A {}
interface B extends A{}

public class FuTest {

  ExecutorService es;
  Callable<B> task;
	
  void doIt() throws InterruptedException, ExecutionException {
	Future<A> futA = null;
	Future<B> futB = null;
	/* Does not type check: */
//	futA = es.submit(task);		
	futB = es.submit(task);
	A a = futB.get();
	a = futA.get();
  }
}

Ripe Allocations, revisited

In the light of the Post Depletion Adjustment of Procedures we made another attempt to get another IP to solve our Tor and SSL problems (see here), and behold! This time we got it in a jiffy!

Tags : ,