Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The concept of Java generics and Type type system

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "the concept of Java generics and Type type system". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let the editor take you to learn the concept of Java generics and the Type type system.

1 Type type system of JAVA

First take a look at java's Type type system (class = > type). Type is the common interface of all types (primitive type-Class, parameterized type-Parameterizedtype, array type-GenericArrayType, type variable-TypeVariable, basic type-Class). The Class mentioned in the first two reflections and comments is an implementation class of Type.

There are four subinterface classes ParameterizedType, TypeVariable, GenericArrayType and WildcardType under Type.

List

Represents a generic type, E is a TypeVariable type, List is a ParameterizedType (parameterized type), and String in List is called an actual parameter type

When you specify types in generics, you can use? Extends or? Super to represent inheritance relationships, such as List, and inside? Called wildcard type WildcardType

GenericArrayType represents an array type whose element type is ParameterizedType (parameterized type) or TypeVariable (type variable), such as T [] or List

[]

Annotations just appeared in JDK1.5. In order to represent the annotated type, add the AnnotatedElement type, which literally means the annotated element. JDK1.8 also has AnnotatedType to associate Type with the concept of annotated elements.

AnnotatedType also has four subinterfaces, which correspond to the four subinterfaces of Type. For example, if the ParameterizedType type is annotated, it is parsed by the compiler into AnnotatedParameterizedType: @ AnTest ("list") List.

List

2 the concept of generics

Java generics is a new feature introduced in JDK1.5, its essence is parameterized type, which solves the problem of uncertain specific object type; the data type it operates on is specified as a parameter (type parameter), which can be used in the creation of classes, interfaces, and methods, respectively, called generic classes, generic interfaces, and generic methods.

Generics: special types that defer type-specific work until object creation or method invocation.

3 examples of generic classes and generic methods

Definition of generic classes

Public class MainTest {private T param;} public static void main (String [] args) {MainTest data = new MainTest () {}; ParameterizedType genType1 = (ParameterizedType) data.getClass (). GetGenericSuperclass ();}

Definition of generic methods

Public class MainTest {public static void main (String [] args) {printData ("siting");} static T printData (T t) {System.out.println (t); return t;}}

Both interfaces and abstract classes can use generics

4 type erasure

When you create an instance of a generic type, jvm erases the specific type; the compiled bytecode does not contain the type parameter in the generic type, that is, ArrayList

And ArrayList are both erased to ArrayList, that is, they are erased to "native type", that is, public class MainTest {public static void main (String [] args) {List strArr = new ArrayList (); List intArr = new ArrayList (); Type strClazz = strArr.getClass (); Type intClazz = intArr.getClass ();}}

See how the compiled bytecode file is represented: idea menu-> view-> show ByteCode

Public class MainTest {T param; public static void main (String [] args) {MainTest test = new MainTest (); test.setParam ("siting");} public T getParam () {return param;} public void setParam (T param) {this.param = param;}} public class com/MainTest {... Omit public static main ([Ljava/lang/String;) V L0 LINENUMBER 7 L0 NEW com/MainTest DUP INVOKESPECIAL com/MainTest. () V ASTORE 1 L1 LINENUMBER 8 L1 ALOAD 1 LDC "siting" / / setParam (Object) INVOKEVIRTUAL com/MainTest.setParam (Ljava/lang/Object;) V L2 after call type erasure. The return value for omitting / / getParam is Object public getParam () Ljava/lang/Object; L0 LINENUMBER 10 L0 ALOAD 0 GETFIELD com/MainTest.param: Ljava/lang/Object; ARETURN. The input parameter omitting / / setParam is Object public setParam (Ljava/lang/Object;) V L0 LINENUMBER 11 L0 ALOAD 0 ALOAD 1 PUTFIELD com/MainTest.param: Ljava/lang/Object; RETURN.}

You can see that T (String) is converted to Object, and the initial initialization String is missing.

5 inheritance of generics

A subclass can specify the generic parameters of the parent class, which can be known classes (Integer, String, etc.), or with its own generic parameters

When a generic type is inherited and the parent class generic parameter is specified, the additional generated ParameterizedType type is used as the parent class of the subclass; if no parent class generic parameter is specified, the native type is inherited directly

Public class MainTest {T param; static public class SubTest1 extends MainTest {} static public class SubTest2 extends MainTest {} / / SubTest3 inherits the temporal native type static public class SubTest3 extends MainTest {}}

6 generic variable TypeVariable

(first define a name temporarily, Test

TypeVariable: the generic parameter of a generic type is TypeVariable; when the parent class uses the generic parameter of the subclass to specify its own generic parameter, or when the generic property is defined in generic class An and uses the generic parameter T of generic class A, its generic parameter is determined by the compiler to be the generic variable TypeVariable instead of being erased by public class MainTest {List param Public static void main (String [] args) throws Exception {Class clazz = MainTest.class; TypeVariable [] typeVariable = clazz.getTypeParameters (); / / 1 Field field = clazz.getDeclaredField ("param"); ParameterizedType arrayType = (ParameterizedType) field.getGenericType (); / / interface List's generic type E is specified by T, so it is recognized as TypeVariable TypeVariable variable1 = (TypeVariable) arrayType.getActualTypeArguments () [0] / / 2 ParameterizedType type = (ParameterizedType) SubTest.class.getGenericSuperclass (); TypeVariable variable2 = (TypeVariable) type.getActualTypeArguments () [0];} static class SubTest extends MainTest {}

7 Parametric type ParameterizedType

Public interface ParameterizedType extends Type {/ / get the actual parameters. If the String; in List is List, it is the TypeVariable type Type [] getActualTypeArguments (); / / get the original type List-> List Type getRawType (); Type getOwnerType ();}

It is important to note that we cannot directly get the type of a generic type that specifies specific parameters, such as Class clazz = List

The Class of the object created directly from the generic class new is not the ParameterizedType type, but the class of the generic type itself, as shown in the following example: public class MainTest {public static void main (String [] args) {MainTest str = new MainTest (); Class variable = str.getClass (); Type genType1 = variable.getGenericSuperclass ();}}

Generics that are specifically parameterized can be recognized as ParameterizedType types by the compiler. There are three ways to get ParameterizedType types.

/ 1 when a subclass inherits a generic, specify a specific parameter (either a known type such as String, or a generic parameter of a subclass) / / 2 to obtain the generic properties defined within the class. You need to specify a specific generic parameter / / 3 local code. You can obtain the generic type public class MainTest {List list through the anonymous internal subclass of the generic (specific generic parameters are required). Public static void main (String [] args) throws NoSuchFieldException {SubTest str = new SubTest (); / / Mode-Class variable = str.getClass (); / / the parent class is ParameterizedType type ParameterizedType genType = (ParameterizedType) variable.getGenericSuperclass (); / / the primitive type of ParameterizedType type is class com.MainTest Type clazz = genType.getRawType () / / the primitive type of MainTest.class is class com.MainTest Class rawClazz = MainTest.class; / / Mode II, generic attribute Field field = rawClazz.getDeclaredField ("list"); / / attribute list type is (546) ParameterizedType type List ParameterizedType fieldType = (ParameterizedType) field.getGenericType (); / / Mode 3 MainTest sub3 = new MainTest () {} / / clazz3 is an anonymous subclass Class clazz3 = sub3.getClass (); / / the parent class is ParameterizedType type ParameterizedType genType3 = (ParameterizedType) clazz3.getGenericSuperclass (); / / the primitive type of ParameterizedType type is class com.MainTest Type type3 = genType3.getRawType ();} public static class SubTest extends MainTest {}}

8 wildcard characters (WildcardType)

Unbounded wildcards: unbounded wildcards? You can adapt to any reference type:

When a method parameter needs to be passed in a generic type and its type cannot be determined. Directly using generics without specific generic variables is easy to cause security risks; if type conversion is carried out in the method code, ClassCastException errors are very easy to occur.

Why don't you just replace generic variables with Object? But generic class + ParameterizedType (parameterized type) with concrete parameter transformation does not have inheritance relationship; that is, Object is the parent class of String, but List and List

Are two different ParameterizedType, and there is no inheritance relationship So there is a type wildcard? public static void print (List list) {}-> > public static void print (List list) {}

Unbounded wildcards can match any type; but in use? You can't set a value for a variable of a generic class because we don't know what the specific type is; if you force a new value, the subsequent reading is prone to ClassCastException errors. Therefore, the compiler restricts the generics of the * wildcard? * * to read but not write.

Upper bound wildcard

< ? extends E>

If you want to receive a List collection, it can only manipulate elements of numeric types [Float, Integer, Double, Byte, etc.]. What do you do? You can use List to indicate that the elements in List are subclasses of Number

Public static void print (List

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report