Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics of generics of

I have a generic class which represents a fragment of text. That fragment of text may have any of a number of different modes (different types of highlighting). Those modes are represented by an Enum. The Enum could be different for each project but it must implement an interface which provides a method to combine 2 of them (could be highlighted and bolded). So i have an interface:

public interface TextFragmentMode<E extends Enum<E>> {
    /**
     * Will combine the supplied mode with the current mode and return the
     * result.
     * 
     * @param mode The mode to combine with.
     * @return The combined mode.
     */
    public E combine( E mode );
}

Then my TextFragment is a container for both a String of text, and a mode. But when I try to declare the class:

public class TextFragment<E extends TextFragmentMode<E extends Enum<E>>> {
    StringBuilder text;
    E mode;
    ...

I get the following error:

Syntax error on token "extends", , expected

Which, according to eclipse syntax highlighting, is referring to the

E extends Enum<E>

portion of the code. Does anyone know what I am doing wrong? I must be missing something about Generics...

--------------------- edit -------------------

I'm finally taking the time to read Effective Java by Josh Bloch (second edition), and it turns out he goes over this use case as Item 34: Emulate extensible enums with interfaces. As much as I would like to say great mind think alike... That would be WAY too presumtuous!

like image 264
Lucas Avatar asked Nov 22 '10 17:11

Lucas


1 Answers

TextFragment<E> needs to say two things about E.

  • It "extends" TextFragmentMode<E>.
  • In order to do that, you must also constrain it to extend Enum<E>.

Because of Java inheritance wonkiness, you need to write that the other way around:

public class TextFragment<E extends Enum<E> & TextFragmentMode<E>> {
like image 158
Tom Hawtin - tackline Avatar answered Sep 27 '22 19:09

Tom Hawtin - tackline