beryx / text-io

A library for creating interactive console applications in Java
http://text-io.beryx.org/
Apache License 2.0
342 stars 45 forks source link

TextTerminal is a raw type. References to generic type TextTerminal<T> should be parameterized #7

Closed tonypiazza closed 6 years ago

tonypiazza commented 6 years ago

I see a Java compiler warning when declaring a variable of type TextTerminal:

TextTerminal is a raw type. References to generic type TextTerminal should be parameterized

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

siordache commented 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);
siordache commented 6 years ago

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.