Skip to main content

Java Enum definition


I thought I understood Java generics pretty well, but then I came across the following in java.lang




Class Enum<E extends Enum<E>>



Could someone explain how to interpret this type parameter? Bonus points for providing other examples of where a similar type parameter could be used.



Cheers, Don.


Source: Tips4allCCNA FINAL EXAM

Comments

  1. It means that the type argument for enum has to derive from an enum which itself has the same type argument. How can this happen? By making the type argument the new type itself. So if I've got an enum called StatusCode, it would be equivalent to:

    public class StatusCode extends Enum<StatusCode>


    Now if you check the constraints, we've got Enum<StatusCode> - so E=StatusCode. Let's check: does E extend Enum<StatusCode>? Yes! We're okay.

    You may well be asking yourself what the point of this is :) Well, it means that the API for Enum can refer to itself - for instance, being able to say that Enum<E> implements Comparable<E>. The base class is able to do the comparisons (in the case of enums) but it can make sure that it only compares the right kind of enums with each other.

    I've used something similar in my C# port of ProtocolBuffers. There are "messages" (immutable) and "builders" (mutable, used to build a message) - and they come as pairs of types. The interfaces involved are:

    public interface IBuilder<TMessage, TBuilder>
    where TMessage : IMessage<TMessage, TBuilder>
    where TBuilder : IBuilder<TMessage, TBuilder>

    public interface IMessage<TMessage, TBuilder>
    where TMessage : IMessage<TMessage, TBuilder>
    where TBuilder : IBuilder<TMessage, TBuilder>


    This means that from a message you can get an appropriate builder (e.g. to take a copy of a message and change some bits) and from a builder you can get an appropriate message when you've finished building it. It's a good job users of the API don't need to actually care about this though - it's horrendously complicated, and took several iterations to get to where it is.

    ReplyDelete
  2. Here's the explanation I like best: Groking Enum (aka Enum<E extends Enum<E>>)

    ReplyDelete
  3. The following is a modified version of the explanation from the book Java Generics and Collections:
    We have an Enum declared

    enum Season { WINTER, SPRING, SUMMER, FALL }


    which will be expanded to a class

    final class Season extends ...


    where ... is to be the somehow-parameterised base class for Enums. Let's work
    out what that has to be. Well, one of the requirements for Season is that it should implement Comparable<Season>. So we're going to need

    Season extends ... implements Comparable<Season>


    What could you use for ... that would allow this to work? Given that it has to be a parameterisation of Enum, the only choice is Enum<Season>, so that you can have:

    Season extends Enum<Season>
    Enum<Season> implements Comparable<Season>


    So Enum is parameterised on types like Season. Abstract from Season and
    you get that the parameter of Enum is types that satisfy

    E extends Enum<E>




    Maurice Naftalin (co-author, Java Generics and Collections)

    ReplyDelete
  4. You are not the only one wondering what that means; see Chaotic Java blog.

    “If a class extends this class, it should pass a parameter E. The parameter E’s bounds are for a class which extends this class with the same parameter E”.

    ReplyDelete
  5. This post has totally clarified to me these problem of 'recursive generic types'.
    I just wanted to add another case where this particular structure is necessary.

    Suppose you have generic nodes in a generic graph:

    public abstract class Node<T extends Node<T>>
    {
    public void addNeighbor(T);

    public void addNeighbors(Collection<? extends T> nodes);

    public Collection<T> getNeighbor();
    }


    Then you can have graphs of specialized types:

    public class City extends Node<City>
    {
    public void addNeighbor(City){...}

    public void addNeighbors(Collection<? extends City> nodes){...}

    public Collection<City> getNeighbor(){...}
    }

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.