Closed tonypiazza closed 6 years ago
For TextTerminal, the type parameter bound is the type itself: TextTerminal<T extends TextTerminal<T>>
.
You may recognize here the same pattern as in Enum<E extends Enum< E>>.
The benefit is that in the methods TerminalProperties<T> getProperties()
and boolean registerUserInterruptHandler(Consumer<T> handler, boolean abortRead)
the compiler may know the actual type of the TextTerminal implementation, which is helpful if you use a specific type of TextTerminal:
TextTerminal<?> genericTerminal = TextIoFactory.getTextIO().getTextTerminal();
SwingTextTerminal swingTerminal = new SwingTextTerminal();
// The compiler knows that tt refers to a SwingTextTerminal. No cast is needed in order to call getFrame():
swingTerminal.registerUserInterruptHandler(tt -> tt.getFrame().dispose(), true);
// This will not compile, because getFrame() is not a method of TextTerminal:
// genericTerminal.registerUserInterruptHandler(tt -> tt.getFrame().dispose(), true);
// You have to cast the generic TextTerminal type in order to make the code compile:
genericTerminal.registerUserInterruptHandler(tt -> ((SwingTextTerminal)tt).getFrame().dispose(), true);
Currently, there are several methods in the Text-IO API that use raw types (for example public TextTerminal getTextTerminal()
instead of public TextTerminal<?> getTextTerminal()
) .
I will address this problem in the 3.0 release.
I see a Java compiler warning when declaring a variable of type TextTerminal:
I can get around the issue by declaring the variable like this:
TextTerminal<?> terminal = textIO.getTextTerminal();
I'm curious why you chose to make this type generic. In other words, what benefit is there?
Thanks in advance.
-Tony