In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article focuses on "how to use Java generics to achieve type erasure", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let the editor take you to learn "how to use Java generics to achieve type erasure"!
Preface
First of all, I would like to give you a classic test question.
List L1 = new ArrayList (); List L2 = new ArrayList (); System.out.println (l1.getClass () = = l2.getClass ())
Excuse me, what is the final output of the above code? Students who do not understand generics and those who are familiar with generics should be able to answer them, while those who know something about generics but do not know much about generics may get the wrong answer.
The correct answer is true.
Generics are involved in the above code, and the result of the output is type erasure. Let's talk about generics first.
What is a generics?
Generics in English means generics,generic, while translated into Chinese, generics should mean extensive, and types are types. So generics are types that can be widely applied.
But a more accurate term for generics is to parameterize the type, or you can pass the type as a parameter to a class or method.
So how do you explain type parameterization?
Public class Cache {Object value; public Object getValue () {return value;} public void setValue (Object value) {this.value = value;}}
Suppose Cache can access any type of value, so we can use it in this way.
Cache cache = new Cache (); cache.setValue (134); int value = (int) cache.getValue (); cache.setValue ("hello"); String value1 = (String) cache.getValue ()
The method used is also very simple, as long as we do the correct cast.
However, generics give us a different programming experience.
Public class Cache {T value; public Object getValue () {return value;} public void setValue (T value) {this.value = value;}}
This is the generic type, which parameterizes the type of the value attribute, which is called a parameterized type. And look at how it is used.
Cache cache1 = new Cache (); cache1.setValue ("123"); String value2 = cache1.getValue (); Cache cache2 = new Cache (); cache2.setValue; int value3 = cache2.getValue ()
The most obvious benefit is that it no longer needs to cast the extracted results. But there is another difference.
Generics can parameterize types, but once the parameters are determined, if there is a similar mismatch, the compiler will not pass.
The above code shows that a String object cannot be set into cache2 because generics make it accept only the type of Integer.
Therefore, combining the above information, we can come to the following conclusion.
As simple and crude as normal Object instead of all types, generics allow categories of data to be passed in from the outside like parameters. It provides an extensibility. It is more in line with the purpose of software programming for abstract development.
When the specific type is determined, generics provide a mechanism for type detection, and only matching data can be assigned normally, otherwise the compiler will not pass. Therefore, it is a type safety detection mechanism, to a certain extent, improve the security of the software to prevent low-level errors.
Generics improve the readability of the program code, there is no need to wait until run time to cast, during the definition or instantiation stage, because of the effect of Cache, programmers can guess at a glance the type of data the code is going to operate on.
In the following article, we will normally introduce the knowledge of generics.
Definition and use of generics
Generics can be divided into three types according to their usage.
Generic class.
Generic method.
Generic interface.
Generic class
We can define a generic class like this.
Public class Test {T field1;}
The T in angle brackets is called a type parameter and is used to refer to any type. In fact, T is just a habitual way of writing, if you like. You can write like this.
Public class Test {Hello field1;}
However, for normative purposes, Java still recommends that we use a single uppercase letter to represent type parameters. Common ones such as:
T stands for any general class.
E stands for Element, or Exception exception.
K stands for Key.
V stands for Value and is usually used in conjunction with K.
S stands for Subtype, which will be explained later in the article.
If a class is defined in its form, it is called a generic class.
So how do you use generic classes?
Test test1 = new Test (); Test test2 = new Test ()
Whenever you create an instance of a generic class, assign the corresponding type in angle brackets. T is replaced with the corresponding type, such as String or Integer. You can imagine that when a generic class is created, the interior automatically expands to the following code.
Public class Test {String field1;}
Of course, a generic class cannot accept one type parameter, it can also accept multiple type parameters.
Public class MultiType {E value1; T value2; public E getValue1 () {return value1;} public T getValue2 () {return value2;}} generic method public class Test1 {public void testMethod (T t) {}}
Generic methods are slightly different from generic classes in that the part of the type parameter, the angle bracket, is written before the return value. The T in is called a type parameter, while the T in a method is called a parameterized type, which is not a real parameter at run time.
Of course, the declared type parameter can also be used as the type of the return value.
Public T testMethod1 (T t) {return null;} coexistence of generic classes and generic methods public class Test1 {public void testMethod (T t) {System.out.println (t.getClass (). GetName ());} public T testMethod1 (T t) {return t;}}
In the above code, Test1 is a generic class, testMethod is a common method in a generic class, and testMethod1 is a generic method. However, there is no corresponding relationship between the type parameters in the generic class and the type parameters in the generic methods, and the generic methods always take the type parameters defined by themselves as the standard.
So, for the above code, we can write the test code like this.
Test1 t = new Test1 (); t.testMethod ("generic"); Integer I = t.testMethod1 (new Integer (1))
The actual type parameter of a generic class is String, while the type parameter passed to a generic method is Integer, which you don't want to do.
However, to avoid confusion, if there are generic methods in a generic class, it is best not to have the same name for the type parameters of the two. For example, the Test1 code can be changed to this
Public class Test1 {public void testMethod (T t) {System.out.println (t.getClass (). GetName ());} public E testMethod1 (E) {return e;}} generic interface
Generic interfaces are similar to generic classes, so they go through it at once.
Public interface Iterable {} wildcard?
In addition to expressing generics, there is also this form. huh? It's called a wildcard.
Some students may think, there is already a form, why introduce such a concept?
Class Base {} class Sub extends Base {} Sub sub = new Sub (); Base base = sub
The above code shows that Base is the parent class of Sub, and there is an inheritance relationship between them, so an instance of Sub can assign a value to a Base reference, so
List lsub = new ArrayList (); List lbase = lsub
Does the last line of code hold? Will the compilation pass?
The answer is no.
The compiler won't let it pass. Sub is a subclass of Base, which does not mean that List and List have an inheritance relationship.
However, in real-world coding, there is a need for generics to handle a range of data types, such as a class and its subclasses, for which Java introduces the concept of wildcards.
Therefore, wildcards appear to specify the range of types in generics.
There are three forms of wildcards.
It is called an unqualified wildcard.
Infinitely fixed wildcards are often used in conjunction with container classes. It actually represents an unknown type, so it involves? The operation must have nothing to do with the specific type.
Public void testWildCards (Collection collection) {}
In the above code, the parameters in the method are Collection objects modified by infinitely fixed wildcards, which implicitly express an intention or qualification that the method testWidlCards () does not need to pay attention to the real type in Collection because it is unknown. Therefore, you can only call type-independent methods in Collection.
We can see that when it exists, the Collection object loses the function of the add () method, and the compiler fails.
Let's look at the code again.
List wildlist = new ArrayList (); wildlist.add (123); / / compilation failed
Some people say that it provides a read-only function, that is, it removes the ability to add specific type elements, leaving only functions that have nothing to do with specific types. Regardless of the type of elements loaded in the container, it only cares about the number of elements and whether the container is empty. I think this kind of demand is very common.
Some students may think, since the effect is so small, why quote it?
Personally, I think that by improving the readability of the code, programmers can quickly make a very concise impression of this code when they see it, and can quickly infer the intention of the source code author.
It means that the type is unknown, but we do need to be more precise in the description of the type, and we want to determine the category within a range, such as type An and its subclasses.
[] li3 = new ArrayList [10]; li3 [1] = new ArrayList (); List v = li3 [1]
It can be done with the help of infinitely fixed wildcards, as mentioned earlier? Represents an unknown type, so the operations it involves are basically independent of the type, so jvm does not need to judge the type against it, so it can compile through, but it only provides elements in the array because of wildcards, so it can only read, not write. For example, the local variable v above can only perform get () operations, not add () operations, which have been discussed in the previous wildcard content section.
At this point, I believe you have a deeper understanding of "how to use Java generics to achieve type erasure". 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.