Articles

Type Aliasing in Java?

A problem I often encounter in Java is that I want to say “these two things are the same”, but Java won’t let me. Suppose I want to maintain an int[] array which is always sorted in my program. So, whenever I get one of these things, I can rely on it being sorted. Here’s what I want it to look like:

// find lowest index of matching entry, or return -1 if no match
int findLowest(sorted arr, int value) {
   int index = Arrays.binarySearch(arr,value)
   if(index < 0) { return -1; } // no match
   // matched, so find lowest index
   index = index - 1;
   while(index >= 0 && arr[index] == value) {
       index = index - 1;
   }
   return index + 1;
}

I often find a method like this useful because, when there are multiple ints of the same value, Arrays.binarySearch() doesn’t guarantee which is found.

Of course, the above isn’t legal Java though! That’s because there is no way to alias a name (e.g. sorted) with a type (e.g. int[]). Now hold on, you say: you can just use int[] above, instead of sorted, and it will work fine! True. But, I want to use sorted to better document my program. In C, you could use a typedeffor this, and I’ve often found that useful.

So, overall, I think allowing such “type aliases” in Java would help: firstly, by providing better documentation; secondly, by allowing them to be type checked. Now, there are quite a few gritty details to work out, such as the actual syntax for declaring a type alias. I’m not proposing a JSR or anything here, but how about this:

alias sorted of int[]

// find lowest index of matching entry, or return -1 if no match
int findLowest(sorted arr, int value) {
   ...
}

Seems simple enough. Now, if we want aliases to be type checked, then we need a way to turn a given type (e.g. int[]) into an alias (e.g. sorted). Well, I suppose a plain-old cast could do the job:

alias sorted of int[]

// find lowest index of matching entry, or return -1 if no match
int findLowest(sorted arr, int value) {
   ...
}

sorted createSorted(int[] unsorted) {
   Arrays.sort(unsorted);
   return (sorted) unsorted;
}

Those type theorists amongst you will immediately raise your arms: what if we subsequently update unsorted and break the sorting guarantee? Well, yup, that could happen. And, without something like uniqueness types, there’s not much we can do. But, perhaps we can just live with it, given that we’re already living with similar issues related to generics and erasure.

Anyhow, it’s just a thought. And, I’m obviously not the first person to some with this idea (see e.g. this, this and this).

7 comments to Type Aliasing in Java?

  • Norswap

    You can just do:

    class MyType extends WhateverYouWant {}

    Granted, it’s a bit hackish and may incur a tiny weeny performance overhead, but it seems to work well otherwise. You’ll need a cast once a while tough.

  • Johnie

    Use a custom annotation

    @Retention(RetentionPolicy.SOURCE)
    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.Parameter})
    @interface Sorted {
    }

    then use it with:

    int findLowest(@Sorted int[] arr, int value) {

    }

    OR

    @Sorted char[] myArray;
    @Sorted String[] myStringArray;

    OR on return values:

    public @Sorted int[] getFunctionName()

    If all you’re looking for is documentation, this is the better strategy than trying to type alias. This is also more accepted and easier to read than type alias.

  • kj

    ie of alias sorted of int[] I propose

    alias int[] sorted;

    private alias int[] sorted; // as in type to name
    This is more inline with
    private static String thing; // as in type name

    The idea just introduces some syntactic sugar without for any guarantees, the sorted does not actual guarantee that is sorted. So I think that an actual object SortedIntArray seems more reliable. And reliability > syntactic sugar.

  • Hey Johnie,

    Yeah, I agree, annotations are a good solution here — why did I think of that!!

    D

  • Probably it’s not what you need but it’s seems to me a nice utility…

    /**
    *
    *
    *
    **/
    public class Alias {

    private T val;

    // create an alias for a “type”
    public static Alias create(T elem) {
    Alias val = new Alias();
    val.val = elem;
    return val;
    }

    // create an alias alias or a copy ;-P
    public Alias me(boolean forceCopy) {
    if (!forceCopy) {
    return (Alias) this;
    }
    Alias val = new Alias();
    val.val = (T) this.val;
    return val;
    }

    // holding value!
    public T value() {
    return val;
    }

    @SuppressWarnings(“unchecked”)
    public <S extends Alias> S as() {
    return (S) this;
    }

    } // END

    /**
    * The Class That Use Alias
    *
    **/
    class UsingAlias {

    public void aMethod(Alias aliasIntArray, Object someOtherValue) {
    System.out.println(someOtherValue + ” –> ”
    + Arrays.toString(aliasIntArray.<Alias> as().value()));
    }

    public static void main(String[] args) {

    int[] arr = { 1, 2, 3, 4, 5 };
    Alias sorted = Alias. create(arr);
    Alias sort2 = sorted. me(false);
    Alias sort3 = sorted. me(true);

    System.out.println(sorted + ” –> ” + sorted.value());
    System.out.println(sort2);
    System.out.println(sort3);

    UsingAlias user = new UsingAlias();
    user.aMethod(sorted, “Hello World!”);

    }
    }

  • peterk

    I would really want this for declaring a static internal class.

    AClass {
    public static class Key
    }

    package another.completely.different.package

    BClass {
    public alias static Key AClass.Key
    }

  • Also, think of copying code from C# to Java (which I do all the time as I write in both languages).

    Imagine if classes were interchangeable between these two languages (java and C#). Think of how much that could benefit the world, especially developers that code in both.

    Look at this C# code.

    string myString = string.empty;

    In Java, it is this:

    String myString = “”;
    if (String.IsNullOrWhiteSpace(myString)
    {
    }

    I need to be able to alias String with a captial S to string with a lowercase S.

    I also need the ability to attach methods/properties/variables to java’s string as String in java doesn’t have String.Empty.

    Also static attachments are needed to support String.IsNullOrWhiteSpace();

    I don’t think C# even supports static attachments. But really, I would like to see these two languages get together to come closer in syntax, even if it is syntaxical sugar.

    If java were to support Aliasing and attachments and properties (as C# does) then life would be much better.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>