In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains why java needs generics. Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor learn why java needs generics.
The concept of generics (why do you need generics)?
First, let's take a look at the following short code:
Public class GenericTest {public static void main (String [] args) {List list = new ArrayList (); list.add ("qqyumidi"); list.add ("corn"); list.add (100); for (int I = 0; I < list.size (); iTunes +) {String name = (String) list.get (I); / / 1 System.out.println ("name:" + name) }}}
Defines a collection of type List, adding two values of type string to it, followed by a value of type Integer. This is fully allowed because at this time the default type of list is the Object type. In later loops, errors like / / 1 are easy to occur because you forget that you also added values of type Integer or other coding reasons to list before. Because the compile phase is normal, a "java.lang.ClassCastException" exception occurs at run time. Therefore, it is not easy to find such errors in the coding process.
In the above coding process, we found that there are two main problems:
1. When we put an object into the collection, the collection does not remember the type of the object, and when the object is extracted from the collection again, the compiled type of the object is changed to the Object type, but its runtime type is still its own type.
two。 Therefore, when fetching collection elements at / / 1, you need to artificially force the type to be converted to a specific target type, and it is easy to have a "java.lang.ClassCastException" exception.
So is there any way for the collection to remember the types of elements in the collection so that as long as there are no problems at compile time, there is no "java.lang.ClassCastException" exception at run time? The answer is to use generics.
What is generics?
Generics, or "parameterized types". When it comes to parameters, the most familiar thing is to have formal parameters when defining a method, and then pass arguments when you call this method. So how do you understand parameterized types? As the name implies, the type is parameterized by the original specific type, similar to the variable parameters in the method, and the type is also defined as a parameter (which can be called a type parameter). Then pass in the specific type (type argument) when using / calling.
It seems a little complicated, first of all, let's take a look at the above example using generics.
Public class GenericTest {public static void main (String [] args) {/ * List list = new ArrayList (); list.add ("qqyumidi"); list.add ("corn"); list.add (100); * / List list = new ArrayList (); list.add ("qqyumidi"); list.add ("corn"); / / list.add (100) / / 1 prompts compilation error for (int I = 0; I < list.size (); iTunes +) {String name = list.get (I); / / 2 System.out.println ("name:" + name);}
After using generic writing, there will be a compilation error when you want to add an object of type Integer at / / 1. Through List, the list collection can only contain elements of type String, so there is no need for type conversion at / / 2, because at this time, the collection can remember the type information of the element, and the compiler has been able to confirm that it is the type of String.
Combined with the above generics definition, we know that in List, String is a type argument, that is, the corresponding List interface must contain type parameters. And the return result of the get () method is directly this parameter type (that is, the corresponding incoming type argument). Let's take a look at the specific definition of List interface:
Public interface List extends Collection {int size (); boolean isEmpty (); boolean contains (Object o); Iterator iterator (); Object [] toArray (); T [] toArray (T [] a); boolean add (E); boolean remove (Object o); boolean containsAll (Collection c); boolean addAll (Collection c); boolean retainAll (Collection c); void clear (); boolean equals (Object o); int hashCode () E get (int index); E set (int index, E element); void add (int index, E element); E remove (int index); int indexOf (Object o); int lastIndexOf (Object o); ListIterator listIterator (); ListIterator listIterator (int index); List subList (int fromIndex, int toIndex);}
We can see that after the generic definition is used in the List interface, the E in represents the type parameter and can receive specific type arguments, and wherever E appears in this interface definition, it represents the same type argument accepted from the outside. Naturally, ArrayList, as the implementation class of the List interface, is defined in the form:
Public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable {public boolean add (E) {ensureCapacityInternal (size + 1); / / Increments modCounting! ElementData [size++] = e; return true;} public E get (int index) {rangeCheck (index); checkForComodification (); return ArrayList.this.elementData (offset + index);} / /. Omit other specific definition processes}
Thus, from the source code point of view, we can see why the Integer type object compilation error is added at / / 1, and the type get () to at / / 2 is directly the String type.
Custom generic interfaces, generic classes, and generic methods
From the above, you have understood the specific operation of generics. You have also learned that interfaces, classes, and methods can also be defined using generics, and used accordingly. Yes, in specific use, it can be divided into generic interfaces, generic classes, and generic methods.
Custom generic interfaces, generic classes, and generic methods are similar to List and ArrayList in the above Java source code. As follows, let's look at one of the simplest generic class and method definitions:
Public class GenericTest {public static void main (String [] args) {Box name = new Box ("corn"); System.out.println ("name:" + name.getData ());} class Box {private T data; public Box () {} public Box (T data) {this.data = data;} public T getData () {return data;}}
In the process of defining generic interfaces, generic classes and generic methods, our common parameters such as T, E, K, V are often used to represent generic parameters, because they receive type arguments passed in from external use. So is the type of the generated object instance the same for different passed-in type arguments?
Public class GenericTest {public static void main (String [] args) {Box name = new Box ("corn"); Box age = new Box (712); System.out.println ("name class:" + name.getClass ()); / / com.qqyumidi.Box System.out.println ("age class:" + age.getClass ()) / / com.qqyumidi.Box System.out.println (name.getClass () = = age.getClass ()); / / true}}
As a result, we find that when using generic classes, although different generic arguments are passed in, different types are not really generated. There is only one generic class passed in different generic arguments in memory, that is, the original most basic type (Box in this example). Of course, logically we can understand it as multiple different generic types.
The reason lies in the purpose of the concept of generics in Java, which only acts in the stage of code compilation. In the process of compilation, after correctly verifying the results of generics, the relevant information of generics will be erased, that is to say, the successfully compiled class file does not contain any generics information. Generic information does not enter the runtime phase.
This can be summed up in one sentence: generic types are logically regarded as many different types, but in fact they are all the same basic types.
Type wildcard
Following the above conclusion, we know that both Box and Box are actually Box types, and now we need to move on to the question of whether logically similar types like Box and Box can be regarded as generic types with a parent-child relationship.
To figure this out, let's go on to look at the following example:
Public class GenericTest {public static void main (String [] args) {Box name = new Box (99); Box age = new Box (); getData (name); / / The method getData (Box) in the type GenericTest is / / not applicable for the arguments (Box) getData (age) / / 1} public static void getData (Box data) {System.out.println ("data:" + data.getData ());}
We found that an error message appeared at code / / 1: The method getData (Box) in the t ype GenericTest is not applicable for the arguments (Box). Obviously, from the prompt, we know that Box cannot logically be regarded as a parent class of Box. So what is the reason?
Public class GenericTest {public static void main (String [] args) {Box a = new Box; Box b = a; / 1 Box f = new Box (3.14f); b.setData (f); / / 2} public static void getData (Box data) {System.out.println ("data:" + data.getData ());}} class Box {private T data Public Box () {} public Box (T data) {setData (data);} public T getData () {return data;} public void setData (T data) {this.data = data;}}
In this example, it is obvious that an error message will definitely appear at / / 1 and / / 2. Here we can use the method of counter-proof to explain.
Assuming that Box can be logically treated as a parent of Box, there will be no error prompts at / / 1 and / / 2, so the question arises: what type is it when fetching data through the getData () method? Integer? Float? Or Number? And because the order in the programming process is uncontrollable, it is necessary to make type judgment and forced type conversion when necessary. Obviously, this contradicts the idea of generics, so logically Box cannot be regarded as the parent of Box.
Okay, so let's go back to the first example in Type wildcard, and we know the underlying reason for the specific error prompt. So how to solve it? Can headquarters define a new function? This obviously runs counter to the idea of polymorphism in Java, so we need a reference type that can be logically used to represent a parent class of both Box and Box, from which type wildcards emerge.
Type wildcards are generally used? Instead of specific type arguments. Note that this is a type argument, not a type parameter! And Box is logically Box and Box.... Wait for the parent class of all Box. As a result, we can still define generic methods to accomplish such requirements.
Public class GenericTest {public static void main (String [] args) {Box name = new Box ("corn"); Box age = new Box; Box number = new Box; getData (name); getData (age); getData (number);} public static void getData (Box data) {System.out.println ("data:" + data.getData ();}})
Sometimes, we may also hear the upper limit of type wildcards and the lower limit of type wildcards. What exactly is it like?
In the above example, if you need to define a method that functions like getData (), but with further restrictions on type arguments: it can only be the Number class and its subclasses. At this point, you need to use the upper limit of type wildcards.
Public class GenericTest {public static void main (String [] args) {Box name = new Box ("corn"); Box age = new Box; Box number = new Box (314); getData (name); getData (age); getData (number); / / getUpperNumberData (name); / / 1 getUpperNumberData (age); / / 2 getUpperNumberData (number) / / 3} public static void getData (Box data) {System.out.println ("data:" + data.getData ());} public static void getUpperNumberData (Box
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.