⬆️ ⬇️

Java extension: aliases

I post this post in order to get feedback from the habra-community of Java-programmers. If there are enough votes in favor, this feature can be sent to Sun for consideration.



Problem





After long work with Java 5 and Java 6 and a small analytics, I came to the conclusion that generics in Java have a number of limitations that prevent you from implementing a solution in a beautiful way, and it is sometimes very nontrivial to bypass them. This statement refers to the development of subsystems that actively use generics (reaching 3-4 generic types with a complex hierarchy in the class description).

')

I will give examples of code that clearly indicate these limitations, as well as the inconvenience of use (consider only the syntax):

 public class A {
     public <X> void method (List <? extends X> list) {
         // processElement (list, list.get (0));  - compilation error
         processElement ((List) list, (Object) list.get (0));  // compilation warning
     }

     public <T> void processElement (List <T> list, T object) {
     }

     public static class B <T extends I1 & I2> {
     }

     // You have to repeat declarations of generic types
     public static class C <T extends I1 & I2> extends AB <T> {
     }
 }






Decision





To solve the voiced problems and inconvenience of use, which reduces the readability of the code, it is proposed to extend the syntax of the language and introduce aliases.

An alias is a generic type declared on the basis of other generic types that can be used within sight.



The easiest way to show an example. Convert the above code using aliases:

 public class A {
     public <X> void method (List <? extends X> list) {
         // processElement (list, list.get (0));  - Compile error

         / *
         Definition?  extends X as T for the type of the variable list (i.e. List <? extends X> -> List <T>).
         The visibility of such a definition is limited to a block.
         However, this definition is used in the same way as generic type T.
         * /
         List <T> list1 = alias <T> (list);

         processElement (list1, list1.get (0));  // Correct
     }

     public <T> void processElement (List <T> list, T object) {
     }


     / *
     Alias ​​N can be used wherever I1 & I3 can be used (in generics).
     Alias ​​N can be used wherever any of the interfaces I1 and I3 could be used.
     Alias ​​N can optionally be used as a variable type, the return value of a method, or a parameter of a method.
     The alias has an access level.
     * /
     public alias N = I1 & I2;

     public static class B <T extends N> {
     }

     // You have to repeat the declaration of one generic type instead of a complex bundle
     public static class C <T extends N> extends AB <T> {
     }
 }




It is assumed that aliases will not be reflected in the byte code, i.e. they are in fact an extension of the syntax of the language, but not semantics. They also allow you to fix a generic-type, which in some cases (see the example above) allows you to avoid cast-s and warning'ov.

Source: https://habr.com/ru/post/93324/



All Articles