Generics were introduced after Java5, which made it more secure for us to manipulate collections or classes during compilation, to make it easier to read code, and to give Java, a compiled language, a dynamic reflection technology, and to make Java work in the framework development, so that it can live. Take a look at what you need to be aware of and understand when using generics and reflection?
1.Java generics are type-erased
????? Generics in Java are valid during compilation and will be deleted during run time, i.e. all generic parameter types will be erased after compilation. See the example below?
Java code???
- publicstaticvoid ? Test ( List?? Testparameter)? {??
- ?
- "??
- ?
- publicstaticvoid ? Test (List?? Testparameter)? {??
- ?
- "??
????? The above is one of the most simple overloaded example, the generic type will be erased after compilation, so whether the list or list will become a list?, so the parameters are the same, the overloads are not valid, and the reader can try to look at the different generic classes getclass (), Their class is the same??
2. Generic parameters and arrays cannot be initialized
????? Please observe the following code?
Java code???
- class ? Test?? {??
- //compile does not pass
- private ? T?t?=? New ? T ();??
- //compile does not pass
- private ? T[]?tarray?=? New ? T[5];??
- //compile through
- private ? List?? List?=?? New ? ArrayList? ();??
- "??
????? The Java language is a strong type, a compiled security language, it needs to ensure the stability and security of the runtime, so at compile time the compiler needs to strictly check the type we declare, the compiler needs to obtain the T type during compilation, but the generics have been erased during compilation, so New T () and new t[5 ] There are compile errors, and why is ArrayList successfully initialized? This is because the ArrayList surface is generic, but during compilation has been transformed from the ArrayList internal to an object, interested readers can look at ArrayList source code, The source contains elements of the private transient object[] elementdata, is an array of type Object?
3. Enforce declaring the actual type of generics
????? When using generics, in most cases you should declare the type of the generic, for example, if the collection is a user object, you should use list to declare it so that you can minimize the type of conversion, and if you use only list instead of declaring generics, then the collection is equivalent to list?
4. Note that generics have no inheritance.
????? Please see the following example?
Java code???
- publicstaticvoid? Main (String[]?args)? {??
- ? compilation does not pass
- ???? List
- ? or
- ???? List
- }??
????? The business logic for the above code is to have a set of elements, but I'm not sure if the element is shaped or floating point, when I make the corresponding generic implementation class after determination, it is possible for the reader of the new contact generic to make the above error, which is understood to be inheritable between generics, such as a generic that declares an object actually creates an integer generic The error is that there is also an inheritance relationship between generics, but this is not true, generics are helpful for developers during compile-time type checking security. Can we implement the above business logic in a different way?
Java code???
- publicstaticvoid ? Main ( String[]?args)? {??
- //number? For integer? Common parent class of Double
- ???? List?? Numberlist?=?? New ? ArrayList? ();??
- ?
- //use wildcards, which represents the actual type is a subclass of number type
- ???? Listextends? Number>?numberlist2?=? New ? ArrayList? ();??
- //or
- ???? Listextends? Number>?numberlist3?=? New ? ArrayList? ();??
- "??
5. Different scenarios use a different wildcard character
???? Wildcard characters are supported in generics, can be used to represent any type by themselves, or you can use the extends keyword in the example above to indicate that an incoming parameter is a subclass of a class or interface, or you can use the Super keyword to indicate that a type's parent type is accepted. Extends and super the same way, extends is the upper bound, super to limit the lower bound?
< Br>6. Recommended order for list? List List?
????? above can accommodate all objects, but the order of use should be the preferred list, then list, and then use list?
7 . Use multiple bounds to qualify
????? now has a business need to be the employee of our company (inherit user), but also need to have the function of the cashier (implement cashier), At this point we can certainly think of accepting 1 user and then judging whether the user implements the cashier interface, but what can we do in a generic world? See the example below?
Java code???
- publicstatic??? extends? User?&? Cashier>?? void? Collectmoney (t?t) {??
- ?
- }??
????? The above example shows that the upper bounds are bounded, as long as the subclass of user and cashier can be passed as a parameter to the method.
====================== I am the dividing line of generics and reflection ====================
8. Notice the particularity of class
????? The Java language is the Java source file is compiled into a suffix class byte-code file, and then through the ClassLoader mechanism to load the class file into memory, the last generation instance execution, in describing a class is, Java uses a meta class to describe the class, this is the class, He is a class that describes classes, so the class is destined to be special?
????? The 1.Class class has no constructors, and the class object is loaded by the JVM by invoking the ClassLoader?
??????? DefineClass method to construct a class object?
????? The 2.Class class can also describe basic data types, because the basic types are not objects in Java, are they?
??????? Generally exist on stacks, but class can still describe them, such as using Int.class?
????? 3. The object is a singleton pattern, a class implementation object describes a category, and describes only one class?
??????? So as long as it's the class that's being described, all objects have only one class instance?
????? The 4.Class class is the gateway to Java reflection?
9. Timely selection of getdeclaredxxx and getxxx
????? There are many getdeclaredxxx and GetXXX methods available in class classes, see the following example?
Java code???
- publicstaticvoid? Main (String[]?args)? {??
- ???? Class?? Cls?=? User.? class;??
- Get class method
- ???? Cls.getdeclaredmethods ();??
- ???? Cls.getmethods ();??
- Get class constructor
- ???? Cls.getdeclaredconstructors ();??
- ???? Cls.getconstructors ();??
- Get class Properties
- ???? Cls.getdeclaredfields ();??
- ???? Cls.getfields ();??
- }??
????? The way to getxxx is to get all public levels, including methods inherited from the parent class, and getdeclaredxxx to get all of them, including public, private, unrestricted, and access rights.
10. Set accessible to True when reflection accesses a property or method
????? Is it a well-known notation to check accessible before invoking the constructor or method's invoke, such as the following code?
Java code???
- publicstaticvoid? Main (String[]?args)? throws? Exception? {??
- ???? Class?? Cls?=? User.? class;??
- Creating objects
- ???? User?user?=?cls.newinstance ();??
- ?
- Get the test method
- ???? Method?method?=?cls.getdeclaredmethod ("test");??
- ?
- Check the Accessible property
- if (!method.isaccessible ()) {??
- ???????? Method.setaccessible (true);??
- ????}??
- ???? Method.invoke (user);??
- }??
????? Readers can try to get the class GetMethod, that is, the public method, and then output isaccessible, you can see the output is also false, in fact, because the semantics of accessible attribute is not our understanding of access rights, but refers to whether to conduct security checks, and security monitoring is very resource-intensive, so the reflection provides accessible options, so that developers evade security checks, interested readers can view the AccessibleObject class to observe their source code to understand the security check.
11. Dynamic load class using forname
????? Forname believe that readers are not unfamiliar, when using JDBC to dynamically load the database driver is to use the forname way to load, but also can read from the external configuration file the class's full path string to load, when using Forname, the loaded class will be loaded into memory , only the class is loaded, and no code is executed, and our database driver uses the static block of code to perform the operation because the static code block is executed when the class is loaded into memory.
12. Use reflection to make the template method more powerful
????? The template method is defined as defining an algorithmic skeleton of an operation, delaying certain steps into a subclass, and implementing the details subclasses decide that the parent class only determines the skeleton, and the following is a case of a traditional template method?
Java code???
- publicabstractclass ? Test? {??
- ?
- publicfinalvoid ? dosomething ( )? {??
- ???????? System.out.println ("Start ...");??
- ???????? Doinit ();??
- ???????? System.out.println ("End ...");??
- ????}??
- ?
- protectedabstractvoid ? doinit ();??
- "??
??? At this point the subclass only needs to inherit the test class implementation Doinit () method can be embedded into the dosomething, now we have a requirement, if I need to call a series of methods in DoSomething to complete dosomething? And the number of methods I call is not certain. , you can add methods to the DoSomething method by simply following some rules. See the code below?
Java code???
- publicabstractclass? Test? {??
- ?
- publicfinalvoid? dosomething ()? throws? Exception? {??
- ?
- ???????? Method[]?methods?=? this. getclass (). Getdeclaredmethods ();??
- ???????? System.out.println ("Start ...");??
- for? (method?method?:?methods)? {??
- if? (this. Checkinitmethod (method))? {??
- ???????????????? Method.invoke (this);??
- ????????????}??
- ????????}??
- ???????? System.out.println ("End .....");??
- ????}??
- ?
- Privatebooleancheckinitmethod (method?method)? {??
- ? The method name is initialized as Init
- returnmethod.getname (). StartsWith ("Init")??
- ? is the public decorated
- ???????????????? &&? Modifier.ispublic (Method.getmodifiers ())??
- ? Whether the return value is void
- ???????????????? &&?method.getreturntype (). Equals (Void.type)??
- ? Whether there are no parameters
- ???????????????? &&?! Method.isvarargs ()??
- ? is abstract type
- ???????????????? &&?! Modifier.isabstract (Method.getmodifiers ());??
- ????}??
- }??
????? See the above code, readers have the feeling of déjà vu? Is it possible to become a test class when using JUNIT3 as long as the method's signing convention is followed? Using this reflection can make the template method more powerful, and next time you need to use more than one method in the template method, do not create multiple abstract methods, try using the above method?
13. Do not focus too much on the efficiency of reflection
????? The efficiency of reflection is a commonplace problem, the normal method of invocation, the creation of classes, in the case of reflection need to invoke a lot of APIs to achieve, efficiency is certainly lower than normal circumstances, but in the project really cause performance problems, the large number will not be caused by reflection, and reflection brought us is so wonderful, Today's series of open-source frameworks, almost all of the reflection of the figure, and a large number of more abound, so that the Sleeping beauty of Java to live, non-reflective mo?
Summarize:?
????? In this article only from the "Improve Java program 151 recommendations" to extract part of the summary of the narrative, recommend readers to buy this book, the book not only from the case study, but also related to the principle, the bottom of the implementation, not only tell you how to do, but also tell you why to do so.?
Java High-quality code-generics and reflection