Notes on implementing concise calls to constructors with type parameters
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Fri May 15 16:27:23 PDT 2009
On *Fri*, May 15, 2009 at 14:01:02, Joseph D. Darcy <Joe.Darcy at
sun.com<http://mail.openjdk.java.net/mailman/listinfo/coin-dev>>
wrote:
:
> Raw types were of course a compromise as part of bring generics to an
> established language and its existing libraries.
>
> Their use should be avoided in new code and the compiler should help
> users in this regard.
>
> One step in that direction is that compiler(jdk1.7+) to use hidden diamond
operator in some cases.
By adding below simple rule:
code sample:
Cell<String> cs = new Cell(1);
Rule:
if instantiated object type(in new Cell(1), Cell class) is generic class
then goto GENERIC_CASE
GENERIC_CASE:
treated as :
Cell<String> cs = new Cell<>(1);
and this treated as:
Cell<String> cs = new Cell<String>(1);
goto Next:
else // raw type(legacy code)
RAW_CASE:
Cell<String> cs = new Cell(1);
Next:
And finally catching compile time error for generic code.
I think one of main goals of adding generic support to java language
was catching run time exceptions in compile time and having robust and
safe code.
I don't think the Cell class to be a legacy code(row type)in this case.
I think this particular rule can be applicable at least in Object
instantiation case.
if right hand side is not a generic type use the row type.
Cell<String> cs = new LegacySubCell(10);
By diamond operator if we use:
Cell<String> cs = new LegacySubCell<>(10);
compiler got an error, because LegacySubCell is not generic
class(legacy code).
But by my rule(no diamond operator in code) this compiles fine.
because that the LegacySubCell class is not generic(legacy code)
treated as row type.
By this rule we decrease the use of row types and not dropping them
totally ones.
One advantage of this rule is that if some day we decided to update
legacy code and generified them.
By recompiling code, in this time the compiler would use the generic
LegacySubCell class and
We would had:
the code:
Cell<String> cs = new LegacySubCell(10);
treated as
Cell<String> cs = new LegacySubCell<>(10);
and this treated as:
Cell<String> cs = new LegacySubCell<String>(10);
And finally catching compile time error.
I think we don'nt need to the first step and diamond operator to be hidden.
And we have:
Cell<String> cs = new Cell(1);
if Cell is generic class
then goto GENERIC_CASE
GENERIC_CASE:
treated as :
Cell<String> cs = new Cell<String>(1);
goto Next:
else // raw type(legacy code)
RAW_CASE:
*Cell<String> cs = new Cell(1);
Next:
One note: By this rule we don't need to change code for using new
generic versions of legacy classes.
Another example:
List<String> myList = new ArrayList();
treates as: GENERIC_CASE
List<String> myList = new ArrayList<String>();
because that ArrayList is now generic class(since 1.5).
But the following code:
List<String> myLegacyList = new MyCustomLegacyList();
is treated as: Raw_CASE
List<String> myLegacyList = new MyCustomLegacyList();
and some day if I update MyCustomLegacyList class(generified it) and recompile
above code without changing code:
Compiler(jdk 1.7+) in this time must behave as below:
List<String> myLegacyList = new MyCustomLegacyList();
Must be treated as: GENERIC_CASE
List<String> myLegacyList = new MyCustomLegacyList<String>();
Therefore by this rule we can slowly remove row types from language(by
compiler help).
More information about the coin-dev
mailing list