Disadvantages of the Java collection: type unknown

Source: Internet
Author: User
Tags int size gopher tostring

The

Disadvantage of using a Java collection is the loss of type information when an object is placed in a collection. This happens because the programmer at the time of the collection did not know exactly what type the user wanted to put into the collection. Indicating that a collection allows only a specific type prevents it from becoming a "general-purpose" tool that can cause trouble to users. To solve this problem, the collection actually holds the handle of some objects of type object. This type of course represents all objects in Java, because it is the root of all classes. Note, of course, that this does not include basic data types, as they are not inherited from "anything." This is a good solution, except that it does not apply to the following:
(1) When an object handle is placed in the collection, any type of object can enter our collection, even if it is specifically indicated that it can hold only a particular type of object, because the type information is discarded. For example, although it is indicated that it can only hold a cat, anyone can actually throw a dog in.
(2) because type information no longer exists, the only thing a collection can be sure of is that it holds a handle to an object. Before you can use it formally, you must sculpt it so that it has the correct type.

It is gratifying to note that Java does not allow people to misuse the objects that are placed in the collection. If you throw a dog into a cat's collection, you still treat everything in the collection as a cat, so you get an "illegal" error when using that dog. In the same sense, if you try to "sculpt" a dog's handle to a cat, you will still get an "illegal" error during the run.
The following is an example:
 

//: Catsanddogs.java//Simple Collection example (Vector) import java.util.*;
  Class Cat {private int catnumber;
  Cat (int i) {catnumber = i;
  } void Print () {System.out.println ("Cat #" + catnumber);
  } class Dog {private int dognumber;
  Dog (int i) {dognumber = i;
  } void Print () {System.out.println ("Dog #" + dognumber);
    } public class Catsanddogs {public static void main (string[] args) {Vector cats = new vector ();
    for (int i = 0; i < 7; i++) cats.addelement (new Cat (i));
    Not a problem to add a dog to Cats:cats.addElement (new Dog (7));
    for (int i = 0; i < cats.size (); i++) ((Cat) Cats.elementat (i)). Print (); Dog is detected only at Run-time}}///:~ 


You can see that vector usage is very simple: first create one, then place the object with AddElement (), and then get those objects with ElementAt () (note that the vector has a size () method that lets us know how many elements have been added, In order to prevent the mistake of exceeding the boundary and causing the error of violation.
Cat and Dog classes are very straightforward--except that they are all "objects," they are nothing special (if you do not explicitly specify what class to inherit from, you default to inherit from object.) So we can not only put cat objects into this collection with vector methods, but also add dog objects without any error prompts at compile time and runtime. When the Vector method ElementAt () Gets the object that is supposed to be cat, it actually obtains a handle that points to an object, and the object must be shaped as cat. Then you need to enclose the entire expression in parentheses, forcing the styling before calling the print () method for cat, or a syntax error will occur. During the run, if you try to sculpt a dog object as cat, you get an illegal violation.
The implications of these treatments are far-reaching. Although it seems to be a bit of a hassle, it is guaranteed by security. It is hard for us to accidentally cause some hidden mistakes. If a part of a program (or several parts) inserts an object into a set, we just have to find the location where the error was inserted, by placing the collection in a part of the program where a wrong object was found. Of course, this can be done by checking the code, but this is probably the dumbest debugging tool. On the other hand, we can start our own programming from some standardized collection classes. Although they are functionally deficient and clumsy, they guarantee no hidden errors.

1. Errors are sometimes not revealed
in some cases, the program seems to work correctly, not styling back to our original type. The first case is quite special: the String class gets extra help from the compiler to work properly. As long as the compiler expects a string object, but it does not get one, it automatically invokes the ToString () method defined in object and capable of being overwritten by any Java class. This method generates a string object that satisfies the requirement and is then used when we need it.
Therefore, all you have to do to get the object of your class to show up is to overwrite the ToString () method, as in the following example:
 

//: Worksanyway.java//In special cases, things just seem//to work correctly. Import java.util.*;
  Class Mouse {private int mousenumber;
  Mouse (int i) {mousenumber = i;
  }//Magic method:public String toString () {return ' This is Mouse # ' + mousenumber;
    } void Print (String msg) {if (msg!= null) System.out.println (msg);
  System.out.println ("Mouse number" + Mousenumber); } class Mousetrap {static void Caughtya (Object m) {Mouse Mouse = (Mouse) m;//Cast from Object mouse.print (
  "Caught one!");
    } public class Worksanyway {public static void main (string[] args) {Vector mice = new vector ();
    for (int i = 0; i < 3; i++) mice.addelement (new Mouse (i));
      for (int i = 0; i < mice.size (); i++) {//No cast necessary, automatic call//To Object.ToString ():
      System.out.println ("Free Mouse:" + mice.elementat (i));
    Mousetrap.caughtya (Mice.elementat (i)); }
  }
} ///:~

The


can see the redefinition code for ToString () in mouse. In the second for Loop of main (), you find the following statement:

System.out.println ("Free Mouse:" +
Mice.elementat (i));

after "+", the compiler expects to see a string object. ElementAt () generates an object, so the compiler calls ToString () by default for the desired string. Unfortunately, it is only for strings that you can get results like this, and no other type of conversion will do that. The second method of the
hidden styling has been applied in Mousetrap. The Caughtya () method receives not a mouse, but an object. It is then styled as a mouse. Of course, this is a very bold thing to do, because by receiving an object, anything can be passed to the method. However, if the styling is not correct-if we pass the wrong type-a violation error will be obtained during the run. This, of course, is not checked at compile time, but can still prevent the problem from happening. Note that you do not need to sculpt when using this method:
Mousetrap.caughtya (Mice.elementat (i));

2. Generate vectors that automatically discriminate types
You may not want to give up that question. A more "robust" scenario is to create a new class with vector that receives only the type we specify, and only the type we want. As follows:
 

//: Gophervector.java//A type-conscious Vector import java.util.*;
  Class Gopher {private int gophernumber;
  Gopher (int i) {gophernumber = i;
    } void Print (String msg) {if (msg!= null) System.out.println (msg);
  System.out.println ("Gopher number" + Gophernumber);
  } class Gophertrap {static void Caughtya (Gopher g) {G.print ("caught one!");
  } class Gophervector {private vector v = new vector ();
  public void AddElement (Gopher m) {v.addelement (M);
  Public Gopher elementat (int index) {return (Gopher) v.elementat (index);
  public int size () {return v.size ();}
    public static void Main (string[] args) {Gophervector gophers = new Gophervector ();
    for (int i = 0; i < 3; i++) gophers.addelement (new Gopher (i));
  for (int i = 0; i < gophers.size (); i++) Gophertrap.caughtya (Gophers.elementat (i)); }
} ///:~


This previous example is similar to the fact that the new Gophervector class has a private member of type vector (some trouble with vector inheritance, a reason to know later), and the method is similar to vector. However, it does not receive and produce ordinary objects, and is only interested in the Gopher object.
Since Gophervector only receives one gopher (gopher), so if we use:
Gophers.addelement (New Pigeon ());
An error message is obtained during compilation. In this way, although it is more depressing from a coding standpoint, you can immediately determine whether the correct type is being used.
Note that you do not have to sculpt when using ElementAt ()-It must be a gopher.

3. Parameterized type
Such problems are not isolated-we often create new types on other types of foundation. At this point, it is helpful to have specific types of information during compilation. This is the concept of "parameterized type". In C + +, it is directly supported by the language through "templates". At the very least, Java retains the keyword generic and expects one day to be able to support parameterized types. But we are not sure when this day will come.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.