Union types in Java?

In C/C++ union types are useful in coding dynamic type systems. Does anyone know if this is possible in Java? I don't see any "union" types in my Java book. Perhaps there is a "work around"? Can a cell in an array be a union?

Edit: Is reflection necessary to discover type information in a dynamic context?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

OO: Class hierarchy

You might want to look into using subclasses to achieve the desired union effect. For example, you could create a MyUnionType class and subclasses Foo and Bar:

class MyUnionType {
   // ...
}
class Foo extends MyUnionType {
   // ...
}
class Bar extends MyUnionType {
   // ...
}

Now, if you have an array of type MyUnionType, it can contain MyUnionTypes, Foos and Bars.

About your question to use reflection, you could just use the instanceof operator to obtain some type information. However, it is often better to give MyUnionType a method that both subclasses can override. At runtime, the correct overridden method will be called.

Nope

Union types were specifically not included in Java, due to the security and type-safety issues they caused in C, and because Java has safer and more expressive ways to code instance-level polymorphism. Your best bet for implementing a dynamic type system is munging up something with an explicit type descriptor and a java.lang.Object payload.

Going forward, Scala does provide something approximating union types, with case classes, although due to pattern matching those are much more powerful than simple unions.

C Style Unions

C style unions allow the same bit pattern to be interpreted in multiple ways. For instance, it's common to use a union to pack/unpack a fixed length binary blob into its constituent fields. That's useful in some systems programming contexts, but it's a very low level feature and was excluded from Java since it doesn't make any sense for Java's design goals. In fact, you won't find anything like it in most languages.

In C/C++ union types are useful in coding dynamic type systems. Does anyone know if this is possible in Java? I don't see any "union" types in my Java book. Perhaps there is a "work around"? Can a cell in an array be a union?

Besides being able to reinterpret bit patterns, C style unions also serve a second purpose when they have a discriminator field to indicate what kind of data is in each instance of the union. In Java, OO in general, and even C++ to a large extent that purpose is subsumed by subclassing. In many functional languages (e.g. Haskell and ML) it's subsumed by sum types.

Is reflection necessary to discover type information in a dynamic context?

Not really - you can use reflection or you can roll your own. In Java you can have a discriminator method declared abstractly in the superclass and declared concretely in subclasses. Depending on what you're doing you may be able to skip discriminator methods and design using OO style polymorphic methods for your core functionality. See also "visitor pattern."

In functional languages like Haskell and ML you would use sum types and pattern matching. This is arguably a form of reflection, but it's a very, very limited form - not conceptually much different from the runtime information needed for OO dynamic dispatch.

OT re: Pattern matching as limited reflection

It does sorta gross me out that e.g. I think Scala's pattern matching turns into a list of if/else's that use instanceof :-}.

Why?

Actually, if you use "sealed abstract class" with "case class" (which is Scala's way of encoding closed sum types) Scala's pattern match can compile down to the JVM bytecode equivalent of a jump table.

Still, you're right that when you pattern match on arbitrary types you do get if/else/instanceof stacks.

But why should that bother you? Pattern matching on sum types in other functional languages turns into similar structures of if/else/tag checking.

Java implementation of the (closed) union type


public class Either<A, B> {
  private Either() { }
	
  public A left() { return null; }
  public B right() { return null; }
	
  public final static class Left<A, B> extends Either<A, B> {
    private A a;
    public Left(A a) { this.a = a; }
    public A left() { return a; }
  }

  public static class Right<A, B> extends Either<A, B> {
    private B b;
    public Right(B b) { this.b = b; }
    public B right() { return b; }
  }
	
  public <C> C either(Map<A, C> f, Map<B, C> g) {
    if(this instanceof Left)
      return f.apply(left());
    return g.apply(right());
  }
}

public interface Map<A, B> {
    B apply(A a);
}

Basically what a Scala class would get translated to.

See an interesting alternative (exploiting the fact that to throw an exception is a nifty way of returning something to the caller) here. I wanted to implement it in Java (is quite straightforward) but the catch is that the type has to extend Throwable.

Typecasting

For instance, it's common to use a union to pack/unpack a fixed length binary blob into its constituent fields.

You don't need a union for that, typecasting onto a struct will work. In fact, a union can be seen as a form on implicit, on-the-fly type casting.

Thanks

Thanks for the interesting information. It is amazing how much there can be to such a simple idea.