In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how to apply Java generics". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to use Java generics.
I. what is generics?
Java generics (generics) is a new feature introduced in JDK 5. Generics provide a compile-time type safety detection mechanism that allows programmers to detect illegal types at compile time.
The simple understanding is that generics specify the type at compile time and reduce the exception caused by the mismatch of object types at run time. Its main use is to improve the reuse rate of our code.
ArrayList in our Java standard library is a typical application of generics:
Public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable {. Public ArrayList (Collection c) {elementData = c.toArray (); if ((size = elementData.length)! = 0) {/ / c.toArray might (incorrectly) not return Object [] (see 6260652) if (elementData.getClass ()! = Object [] .class) elementData = Arrays.copyOf (elementData, size, Object [] .class);} else {/ / replace with empty array. This.elementData = EMPTY_ELEMENTDATA;}} public void sort (Comparator c) {final int expectedModCount = modCount; Arrays.sort ((E []) elementData, 0, size, c); if (modCount! = expectedModCount) {throw new ConcurrentModificationException ();} modCount++;}. Public E get (int index) {rangeCheck (index); return elementData (index);} public boolean add (E) {ensureCapacityInternal (size + 1); / / Increments modCounting! ElementData [size++] = e; return true;}}
In the source code, the E in ArrayList is called a type parameter variable, while the entire ArrayList is called a generic type. We can specify any type except the basic type, such as ArrayList.
In Collection in the source code? The wildcard type represents the upper bound of the type, and the parameterized type may be T or a subclass of T.
Comparator in the source code represents the lower bound of the type (called hypertype qualification in Java Core), indicating that the parameterized type is the supertype (parent type) of this type until Object.
II. Extends and super wildcards
When defining the generic type Generic, you can also use extends wildcards to define the type of T:
Public class Generic {...}
For now, we can only define:
Generic p1 = null;Generic p2 = new Generic (1,2); Generic p3 = null
Because Number, Integer and Double all match.
Non-Number types will not be compiled:
Generic p1 = null; / / compile errorworthy generic
Because String and Object do not match, because they are not Number types or subclasses of Number.
Let's look at an example:
Public class Test {static class Food {} static class Fruit extends Food {} static class Apple extends Fruit {} static class Orange extends Fruit {} public void testExtend () {List list = new ArrayList (); / / cannot safely add any elements of practical significance. If an error is reported, extends is an upper-bound wildcard, so you can only take values and cannot put them. / / because the subclass of Fruit is not only Apple but also Orange, it is impossible to determine whether the specific generic type is Apple or Orange, so putting any type will report an error / / list.add (new Apple ()); / / list.add (new Orange ()); / / you can add null, because null can represent any type of list.add (null) / / can be obtained normally, using java polymorphism Food foot = list.get (0); Apple apple = (Apple) list.get (0);} public void testSuper () {List list = new ArrayList (); / / super is the lower-bound wildcard character, which can store elements, but only instances of the current class or subclass. In the current example, list.add (new Fruit ()) List.add (new Apple ()); / / unable to determine whether Fruit has only one parent class (Object is a super parent) / / so the compilation of the instance placed in Food fails, and you can only put your own instance or subclass instance / / list.add (new Food ()) according to the characteristics of java polymorphism; / / List list2 = new ArrayList (); / / Fruit fruit = list.get (0) / / cannot determine the return type}}
In the testExtend method, because extends is used in generics, when storing elements in list, we cannot determine the specific type of elements in List, that is, it may be Apple or Orange. Therefore, when the add method is called, a compilation error occurs regardless of whether new Apple () or new Orange () is passed in.
After understanding extends, it is easy to understand super, that is, we cannot determine which parent class of the generics in the parameters of the testSuper method is Fruit, so we can only return the Object type when calling the get method. Combined with extends, you can see that when you get a generic element, you use extends to get the type of the upper boundary in the generic type (Fruit in this case), and the scope is even smaller.
Summary:
When using generics, use super when accessing elements.
When getting an element, use extends.
With the above conclusion, let's take a look at the copy () method of the Collections class definition of the Java standard library, and the definition of this copy () method perfectly demonstrates the intentions of extends and super:
Dest is not read inside the copy () method because dest.get () cannot be called to get a reference to T
Src is also not modified inside the copy () method, because src.add (T) cannot be called.
Public class Collections {/ / copy each element of src into dest: public static void copy (List dest, List src) {for (int item0; I III) generic erasure
The generics of Java are pseudo-generics because all generics information is erased during compilation of Java. The first prerequisite for correctly understanding the concept of generics is to understand type erasure. Java generics are basically implemented at the compiler level. Type information in generics is not included in the generated bytecode. Type parameters are added when generics are used and will be removed when the compiler compiles. This process becomes type erasure.
Let's look at an example:
Public class Test2 {public static void main (String [] args) {Map map = new HashMap (); Animal animal = new Animal (); animal.setVegetarian (true); animal.setEats ("fish"); map.put ("cat", animal); String json = new Gson (). ToJson (map); System.out.println (json); Map jsonToMap = fromJson (json); System.out.println (jsonToMap) Animal animal1 = jsonToMap.get ("cat"); System.out.println (animal1.getEats ());} public static T fromJson (String str) {return new Gson (). FromJson (str, new TypeToken () {}. GetType ());}}
The code running on the will prompt the following exception:
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.uaf.rabbitmq.producer.Animal at com.uaf.rabbitmq.producer.Test2.main (Test2.java:30)
The main reason for the exception is this sentence: new Gson () .fromJson (str, new TypeToken () {} .getType ())
When this sentence is actually executed, the T in List does not pass the actual generic parameters, which causes Gson to parse JSON according to LinkedTreeMap, resulting in an error; this is a problem caused by generic type erasure at compile time
To solve this problem, we need to modify the fromJson method.
Public class Test2 {public static void main (String [] args) {Map map = new HashMap (); Animal animal = new Animal (); animal.setVegetarian (true); animal.setEats ("fish"); map.put ("cat", animal); String json = new Gson (). ToJson (map); System.out.println (json); Map jsonToMap = fromJson (json, new TypeToken > () {} .getType ()) System.out.println (jsonToMap); Animal animal1 = jsonToMap.get ("cat"); System.out.println (animal1.getEats ());} public static T fromJson (String str, Type type) {return new Gson () .fromJson (str, type);}}
TypeToken is provided in Gson to solve the problem of generic runtime type erasure, and TypeToken is a class to help us capture generic information like Map. An anonymous inner class was created above so that the Java compiler compiles the generic information into the anonymous inner class, which can then be extracted by the getType () method with reflection API at run time.
At this point, I believe you have a deeper understanding of "how to apply Java generics". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
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.