Generic Java

xiaoxiao2021-03-06  78

Generic Java Java may soon be a big change

Translator: Chen Chen Hou Jie: This article is a Chinese Journal of Primriology, 2001/05. The translation is smooth and the technology is full. Mr. Chen Mr. Chen Mr. Chen, a person in charge of "Programmer" magazine, is reproduced here, thank you for Taiwan readers.

Mr. Chen, Mr. Chen and Mr. Jiang Tao did not reprint this article.

-------------------------------------------------- ------------------------------ Dr. Dobb's Journal Feneric Java. Java May Be in for Some Changes BY PHILIP WADLERPHILIP IS A study, Lucent Technologies. He Can Be Reached At Wadler@research.bell-labs.com. ----------------------- -------------------------------------------------- ------- Java language may soon have a big change. Although the Java system has continuously increased and changing a wide variety of prices in violent speeds, Java Language has almost frozen since INNER CLASSES has been introduced several years ago. Now, Sun has joined Java Community Process (an open plan with formal organization, used to develop and revise Java technical specifications), consider adding generics features for Java languages. Below is a "generic" problem that can be solved. Suppose you want to use Lists, some people want to have List of Bytes, and some want to have List of strings, and some people want to have Lists of Lists of strings. This is simple in the Java language. You can express the three you want to use the same class, and they all have elements that type Class Object, see Table 1 (a). Table 1 / Lists (a) Java (b) Generic Java List uses Class (a) List of Byteslist of stringslist of list of strings -ListListList (b) List of byteslist of stringslist of list of strings -list list > In order to maintain the language, you are forced to do something: Yes, you must remember a fact, that is, you have a list of bytes. Or strings or lists, and after you get out of an element, you must transform it from Class Object to class Byte (or String or List) before you get out of it. Java2's Collection Class Framework is to treat various container categories in this way (where Lists) is covered. Einstein said that everything should be simplified as possible, but do not overview (Everything Should Be As SIMPLE AS Possible, But no SIMPLER). Some people may say that they are too simplified. If we expand the Java language in generic types, it is possible to express information about Lists in a more direct way; see Table 1 (b).

Thus, the compiler can track the record you have a list of bytes (or strings or lists), and you will no longer need to turn the type back to class Byte (or String or List ). In some cases, this is very similar to the Ada language generics or C language Templates. It is also similar to Parametric Polymorphism in the so-called Functional Languages ​​(such as ML and Haskell). Sun's work is affected by some elderly efforts, I refer to Identic Generic Java (GJ). GJ was originally designed by three sets of horses, respectively, Sun's Gilad Bracha and David Stoutamire, Martin Odersky, Swiss Federal Science Society, and I. Bracha has now led a department of Sun, which is incorporated to jet the generic characteristics for Java. Odersky and I are in the relevant expert committee. In this article, I want to describe GJ in a forward-looking attitude to see what the SUN's efforts may appear. Further details of GJ are available from the following websites: http://www.cs.bell-labs.com/~wadler/gj/. The GJ compiler is written by ODERSKY and is currently downloaded by the above sites. This GJ compiler is also the basis of the Java compiler currently served in Sun - although the latter has not supported generics. GJ and GJ compilers are not Sun's products. Several key features of GJ include: compliant with Java. GJ is a super-collection of Java. Each Java is still legal in GJ and has the same meaning as the past. Compatible with the Java Virtual Machine (JVM). GJ is compiled as JVM code. JVM does not need any changes. So Java can perform, GJ can be executed, including on your browser. Compatible with existing program libraries. Both the existing program library can work together with GJ, even if it is compiled Class binary type. Sometimes we can also renovate an old program library, plus new types, do not need to make its source code. For example, Java Collection Class Library can be refurbished, plus generic characteristics. Efficient (effect). Information related to generic types, only is maintained in compile periods (rather than performing). This means that the compiled GJ code is almost completely and the same purpose, the same efficiency Java code is consistent. The GJ compiler works to translate the GJ code back to the general Java code. This translation procedure is just a Type Parameters and plus transformation actions. For example, it translates GJ Class List to Java Class List, plus transformation, and turns from Object to Byte in the necessary place. The results obtained are just like the Java code you are writing without supporting generics. That's why we can easily establish a reason for GJ and existing Java program libraries, which is why GJ can have the same efficiency as Java. In addition, GJ has a so-called transformation, ensuring that the transformation action added by the compiler will not cause errors. At the effect, the type system is a simple logic enough to allow the compiler to prove whether a transformation action is safe.

Under these assurance, since the GJ will be translated into JVM Byte Codes, the Javety and Protectiveness (Security) have also been reserved. GJ How to work let us see two examples, actually understand GJ's way of operation. The first example covers the most basic properties of GJ to establish and verify generic lists. The second example covers some advanced properties, showing you how to write a Generic Method to find a maximum element contained in a list. No matter which example, I will first complete the Java code, and then demonstrate how to rewrite GJ. I will also explain how to turn traditional Java programs to make it compatible with GJ, and finally make a comparison for C Templates and Gj Generics. Example One Display List Interface and Iterator Interface (both are highly simplified according to Java Collections Library), and a Linked List Class that will list List Interface, and a Test Class. The list interface here provides an Add Method that adds a new element to the list, and an Iterator Method used to pass an iterator of the List. As for the Iterator Interface, it provides a Hasnext Method that determines whether iteration has been completed, and a next method, used to get the next element and advance the iterator into a location. LINKED LIST CLASS is actually List Interface, but I am slightly not described. Add Method accepts one item, and Next Method is a backbone. Since every Class is Object's subclass, you can form Lists in Byte, String, List, or any other Class element.

Example One: List interface and iterator interfaceinterface List {public void add (Object x); public Iterator iterator ();} interface Iterator {public Object next (); public boolean hasNext ();} class LinkedList implements List {...} Class test {public static void main (string [] args) {// byte list list xs = new linkedlist (); xs.add (new byte); xs.add (new byte (1)); byte x = (Byte) xs.iterator (). Next (); // string list list ys = new linkedList (); ys.add ("zero"); ys.add ("one"); string y = (string) YS.ITERATOR (). next (); // string list list zss = new linkedList (); zss.add (ys); string z = ((list) zss.iterator (). next ()) .iterator (). next (); // string list treted as byte list byte w = (byte) ys.iterator (). NEXT (); // run-time exception}} Then extract the elements from the middle. The user must remember what the element stored in the list is what is the type, and then it turns it to an appropriate type while the extraction element. The last extraction action requires two transitions. If the user is looking forward to extracting a BYTE from a list of strings, an exception occurs during the execution period. Example 2 is shown in Lists, Iterators, Linked Lists, and a Test Class. Now, each interfaces and class have a type of A, written in the corner bracket, used to express the type of element. Every place in Object, now is now replaced. Each of the previous List, Iterator, or LinkedList, now replaces List , Iterator , or LinkedList . Never need to rely on the user's memory, these parameters are sufficient to illustrate the element type of each List, and no longer need a transition action. From a list of lists, extract elements, now become more apparent. If you try to extract Byte from a list of strings, the compiler pointed out the error.

Example 2: Lists, Iterators, Linked Lists, and Test Class Rewritten in Gjinterface List {Public Void Add (A x); public iterator {public a Next (); Public boolean hasnext ();} class linkedlist {...} Class test {public static void main (string [] args) {// byte list list xs = new LinkedList (); xs.add (new byte (0)); xs.add (new byte); byte x = xs.iterator (). Next (); // string list list YS = new LinkedList (); ys.add ("zero"); ys.add ("one"); string y = ys.iterator (). next (); // String List list > ZSS = new LinkedList > (); zss.add (ys); string z = zss.ITerator (). Next (). Iterator (). Next (); // string List Treated AS Byte List Byte W = YS.ITerator (). next (); // compile-time error}} Lists is heterogenous - they can have any other elements, without any The way can force them to have the same type. However, in GJ, Lists is homogeneous - they must have the same type of elements, and the compiler will make this. If you really need a List, you have different other elements, you should use list . In order to translate Gj to Java language, you must make a special wiping action for each type. A number of quadrants, after wiping, should remove the number of parameters (so List is wiped to be List), an unstried number of types, after wiping, it should be obtained (so byte Wiping is BYTE), and after the number is wiped, the result is Object (which turns into an Object after being wiped). If a Method Call is transmitted, it is a type, the compiler will add the appropriate transformation action for it. Translate the LISTS of the table two to Java code, except that the row of errors is caused by errors). Therefore, a "new rules done according to GJ code", can be compiled with a "Old Routing Library complete according to Java code".

GJ is marked with a corner bracket, which is that C users are familiar with them, and other types of parentheses may be confused. Yes, if using parentheses, the number of types and numerical numbers is difficult to distinguish. It is difficult to distinguish if brackets, type Dimension, and array dimension are used. It is difficult to distinguish if brakks, type, and class body. Alternatively, a complex form such as LinkedList > will bring some problems to the article analyzer (Parser). Because >> is considered a single language (>>>). C requires the user to add additional blank between the two right corners to avoid this problem. GJ users don't have to worry about the same problem, this problem has been resolved by a slightly complex text method. Bridges, Generic Methods, Bounds Next Example Demonstration of advanced generic features, including Bridges, Generic Methods, and Bounds. I intend to write a Java code, search for the biggest elements included in a list, and then demonstrate how to rewrite the GJ. In Java, if you want to make the object to be a longer (size), you should make them comparable interface. Oh, yes, each basic type (such as byte or boolean) has a corresponding object type (such as Byte or Boolean). Example 3 shows the declaration of Comparable Interface, and a Byte Class that implements the interface. Both simplified from Java program libraries. CompareTo Method accepts a number of items and passs back an integer. If the receivable is less than, equal to, or is more than the number of items, it is negative, zero value, or positive value, respectively. Byte Class defines two Methods, one is Compareto (Byte), which is overloaded, and the other is Compareto (Object), which overrides have the corresponding Method in Comparable Interface. The first Method is just just subtracting two Bytes to do this as their comparison. The second Method transforms the object to Byte and then calls the first form. To know, if the first-style received is an object rather than a BYTE, it will cause an error in execution. Therefore, the presence of the second Method is necessary, which causes the first-style called to occur when it is completely consistent. We call the second Method as "bridge" because it connects the first Method (exclusive bytes) and interface method (all objects apply). Example 3 also showed a list of Lists Class and a test used Class. The former has a Static Method to find the largest element in the list. Max Method accepts a non-empty List, which is comparable element, and it is the biggest one in all elements. Test Class demonstrates two call actions. Like previous cases, users must remember what is the type used, and do appropriate transformation.

Booleans did not make Comparable Interface, so if you try to find a maximum of "Booleans is the element", an exception will occur. Example 3: The following is the announcement of Comparable Interface, and the announcement of the Byte Class of the interface. interface Comparable {public int compareTo (Object that);} class Byte implements Comparable {private byte value; public Byte (byte value) {this.value = value;} public byte byteValue () {return value;} public int compareTo (Byte That) {Return this.Value - That.Value;} // bridge public int compareto (object this) {return this.compareto ((byte) That;}}}}}}}}}} class lists {public static comparable max (list xs) {ip Xi = xs.iterator (); comparable w = (comparable) xi.next (); while (xi.hasnext ()) {comparable x = () xi.next (); if (w.Compareto (x) < 0) W = x;} return w;}} class test {public static void main (string [] args) {// Byte List List XS = new linkedlist (); xs.add (new byte); xs .add (new byte); byte x = (byte) Lists.max (xs); // boolean list list ys = new linkedList (); ys.add (new boolean (false)); ys.add ( New Boolean (True); Boolean Y = (Boolean) Lists.max (ys); // Run-Time Exception}} 4 is GJ Recovered code. Comparable Interface now accepts a type of A, indicating that the type will be compared. For example, Class Byte made Comparable interface, then representing a BYTE can be compared to another byte. Comparable Interface requires a Method, typed in compareTo (a), so you can expect that when it is implemented in a Class, it must have markers such as Compareto (Byte). Users no longer need to write Bridge method because it has been automatically completed by the GJ compiler.

Example Four: Code rewritten in GJinterface Comparable {public int compareTo (A that);} class Byte implements Comparable {private byte value; public Byte (byte value) {this.value = value;} public byte byteValue () {Return Value;} public int compareto (byte That) {Return this.Value - That.Value;}} class lists {public static a max (list XS) {ip = xs.iterator (); a w = xi.next (); while (xi.hasnext ()) {a x = xi.next (); if (w.Compareto (x) <0) W = x;} return w;}} class test {public static void main (string [] args) {// Byte Collection LinkedList xs = new linkedList (); xs.add (new byte) ); Xs.add (new byte (1)); byte x = collections.max (xs); // boolean collection LinkedList ys = new linkedList (); ys.add (new boolean (false) ); Ys.add (new boolean (true)); boolean y = collections.max (ys); // compile-time error}} // Translation: COLLECTIONS.MAX (), not before LIS Ts.max (). // The actual technique is almost identical, and the former can be seen by SRC / Java / UtiL / Collections.javamax Method indicates two interesting properties of GJ - Generic Methods and Bounds. Below is the MAX mark full picture: public static a max (list XS) This long sentence tells us that Max Method accepts a list, the element type is a, Remove an element, the type is also A. The most in front of the number A is declared, and it is pointed out that this Method can be arbitrarily type A. INSTANTIATED, as long as A is a Comparable interface.

If a Method has its own type, we call it a "generic method", and a type of homogeneous number must be made to make a known interface (or must be a known Class Subclass), we "Bounded" (restricted). Test Class demonstrates two actual call actions. In the first call action, the compiler automatically derives the number A in the Max Method tag must be turned into Byte, and check the class Byte does have a Bound Comparable . The number of types derived by the second call is Boolean, but it has not made Bound Comparable . Therefore, the Java execution period will have an exception (Exception), and GJ refers out in the compile period. In general, the way to import a Bound is to write "IMPLEMENTS" after the number of, then add an interface name, or write "extends" after the number of 叁, plus a Class name . Whether in the Class HEAD or the Generic Method marker, all numbers can appear, Bounds can appear. Bounding interface or class itself may be numbered, and even a recursive, such as the Bound Comparable in the above example, contains the bounded type A number A. Now, the definition of the eraSure requires an additional re-expand: The type variable is wiped, which is equivalent to the wiping result of its Bound (such a Max Method is wiped as Comparable). As previously said, translation can lead to an appropriate transformation, which will also bring the necessary Bridge methods. As in the previous other words, the GJ code of Example 4 will cause the third Java code (except for the line of mistakes). As you can see, the GJ code is compiled into Java, and its result is like the code written in the case of a wide type. So, just use a special refurbishment mode of the GJ compiler (retrofitting mode), you can always add type information for old-style traditional code, even if you only have a binary Class Files. For example, assume you have a class file, there is a previously described Java version of LinkedList Class, but you want to use it in GJ. Example 5 shows the necessary refurbished files. Example 5: Retrofitting File Class LinkedList Implements Collection {public LinkedList (); Public Void Add (A ELT); public iterator item ();} In order to support independent compilation, GJ compile The additional type (Type-signature) is stored in the JVM Class Files. The Class File file format allows so expansion and is ignored by JVM during execution.

Retrofitter removes the original Java Class file, check whether its type is like the result of "GJ mark after wiping", then generates a new Class file with GJ tag. Java2's entire Collection Class Library has been refurbished in this way. Every public interface, Class, and Method in the program library have an appropriate GJ type, no fish. Since refurbished Class Files is only in the newly added GJ type tag (it will be ignored by JVM during execution period), so you can execute it in a browser compatible with Java 2. No need to reload the Collection Class Library. In most cases, you may eventually want to rewrite the original program library with "数 化 别 别". The benefits of retroduction are, you can do it in your own happiness or convenient time, because, before you can use generic types before you use generic types, you don't need to re-write all old code. Conclusion The Java pristine often uses a generic IDIOM: the element type of some information structure is Object. This kind of practice is simple, but you are forced to track the actual type of elements and need to add additional transformation actions. Conversely, for the Java language plus generic types, although it will increase a little complexity, "tracking element type" and "plus transformation action", but fall in the compiler instead of your body . More particularly, the generic type also has a advantage that the abnormality of the execution period can be converted into an error in the compilation period, which is discovered as soon as possible. Below is one of the authors of Bill Joy, Java language specifications (published in Java One Conference, June 1999): We continue to find various mistakes in the software development phase and place a number of numbers Type system in Java language. For me, the value of this is not to make this language more expressive, but to get rid of various transformations that do not do (or do wrong), make the mistake to discovery after the ship cut back. After shipping, a bug is repaired, and its cost is about 10,000 times more than the shipping. And for programmers, it is a very annoying process. If the bug is caught in the compile period, you can calmly, because the entire code concept is completely in your heart. If the bug is reported from the customer, you need an annoying bug tracking, eventually returning to your desk, or on someone's table, and the original design thoughts will fly to the clouds. You have to reload your quick-taking memory in your head! "". Therefore, grabbing the bug as soon as possible is very good and very valuable. If you see which Java program uses Class Object, usually is a mark, indicating that program can benefit from the use of generic types. You can say that this Class's name is really good - when you see it, you should "object" and take it in generic type. (Translation: American Humor, "Object" action, "Object" meaning) GJ is a language used to add generic characteristics for Java.

转载请注明原文地址:https://www.9cbs.com/read-106211.html

New Post(0)
CopyRight © 2020 All Rights Reserved
Processed: 0.035, SQL: 9